Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 465172f1 authored by Daniel Applebaum's avatar Daniel Applebaum
Browse files

Fix threading in Accounts main screen. Move all UI updates to UI

thread.  

Push unread message counting into the background.

Should increase startup performance and reduce black-screens-of-death
that some Market "commentators" report.

Also, updates the per-account unread message count when email account
is finished synchronizing.

parent 8fd9c4e7
Loading
Loading
Loading
Loading
+23 −0
Original line number Diff line number Diff line
@@ -1537,6 +1537,7 @@ s * critical data as fast as possible, and then we'll fill in the de

    
    
    
    /**
     * Mark the message with the given account, folder and uid either Seen or not Seen.
     * @param account
@@ -1985,6 +1986,28 @@ s * critical data as fast as possible, and then we'll fill in the de
        }
    }
    
    public void getAccountUnreadCount(final Context context, final Account account, 
        final MessagingListener l)
    {
      Runnable unreadRunnable = new Runnable() {
        public void run() {
      
          int unreadMessageCount = 0;
          try {
            unreadMessageCount = account.getUnreadMessageCount(context, mApplication);
          }
          catch (MessagingException me) {
              Log.e(Email.LOG_TAG, "Count not get unread count for account " + account.getDescription(),
                  me);
          }
          l.accountStatusChanged(account, unreadMessageCount);
        }
      };
      
      
      putBackground("getAccountUnread:" + account.getDescription(), l, unreadRunnable);
    }
    
    public void deleteMessage(final Account account, final String folder, final Message message,
            final MessagingListener listener) {
      suppressMessage(account, folder, message);
+4 −0
Original line number Diff line number Diff line
@@ -15,6 +15,10 @@ import com.android.email.mail.Part;
 * changes in this class.
 */
public class MessagingListener {
  
    public void accountStatusChanged(Account account, int unreadMessageCount) {
    }
  
    public void listFoldersStarted(Account account) {
    }

+93 −14
Original line number Diff line number Diff line

package com.android.email.activity;

import java.util.concurrent.ConcurrentHashMap;

import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ListActivity;
@@ -11,6 +13,7 @@ import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Handler;
import android.view.ContextMenu;
import android.view.KeyEvent;
import android.view.Menu;
@@ -32,6 +35,7 @@ import android.widget.AdapterView.OnItemClickListener;
import com.android.email.Account;
import com.android.email.Email;
import com.android.email.MessagingController;
import com.android.email.MessagingListener;
import com.android.email.Preferences;
import com.android.email.R;
import com.android.email.activity.setup.AccountSettings;
@@ -45,6 +49,7 @@ import com.android.email.mail.store.LocalStore.LocalFolder;

public class Accounts extends ListActivity implements OnItemClickListener, OnClickListener {
    private static final int DIALOG_REMOVE_ACCOUNT = 1;
    private ConcurrentHashMap<String, Integer> unreadMessageCounts = new ConcurrentHashMap<String, Integer>();
    /**
     * Key codes used to open a debug settings screen.
     */
@@ -56,6 +61,55 @@ public class Accounts extends ListActivity implements OnItemClickListener, OnCli
    private int mSecretKeyCodeIndex = 0;
    private Account mSelectedContextAccount;
    
    private AccountsHandler mHandler = new AccountsHandler();
    private AccountsAdapter mAdapter;
    
    class AccountsHandler extends Handler
    {
      private static final int DATA_CHANGED = 1;

      public void handleMessage(android.os.Message msg)
      {
        switch (msg.what)
        {
          case DATA_CHANGED:
            if (mAdapter != null)
            {
              mAdapter.notifyDataSetChanged();
            }
            break;
          default:
            super.handleMessage(msg);
        }
      }
      
      public void dataChanged()
      {
              sendEmptyMessage(DATA_CHANGED);
      }

    }
    
    MessagingListener mListener = new MessagingListener() {
      @Override
      public void accountStatusChanged(Account account, int unreadMessageCount)
      {
        unreadMessageCounts.put(account.getUuid(), unreadMessageCount);
        mHandler.dataChanged();
      }
      
      @Override
      public void synchronizeMailboxFinished(
          Account account,
          String folder,
          int totalMessagesInMailbox,
          int numNewMessages) {
        MessagingController.getInstance(getApplication()).getAccountUnreadCount(Accounts.this, account, mListener);
      }
    };

    private static String UNREAD_MESSAGE_COUNTS = "unreadMessageCounts";
    private static String SELECTED_CONTEXT_ACCOUNT = "selectedContextAccount";
    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
@@ -67,17 +121,26 @@ public class Accounts extends ListActivity implements OnItemClickListener, OnCli
        findViewById(R.id.add_new_account).setOnClickListener(this);
        registerForContextMenu(listView);

        if (icicle != null && icicle.containsKey("selectedContextAccount")) {
        if (icicle != null && icicle.containsKey(SELECTED_CONTEXT_ACCOUNT)) {
            mSelectedContextAccount = (Account) icicle.getSerializable("selectedContextAccount");
        }
        if (icicle != null)
        {
          ConcurrentHashMap<String, Integer> oldUnreadMessageCounts = 
            (ConcurrentHashMap<String, Integer>)icicle.get(UNREAD_MESSAGE_COUNTS);
          if (oldUnreadMessageCounts != null) {
            unreadMessageCounts.putAll(oldUnreadMessageCounts);
          }
        }
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        if (mSelectedContextAccount != null) {
            outState.putSerializable("selectedContextAccount", mSelectedContextAccount);
            outState.putSerializable(SELECTED_CONTEXT_ACCOUNT, mSelectedContextAccount);
        }
        outState.putSerializable(UNREAD_MESSAGE_COUNTS, unreadMessageCounts);
    }

    @Override
@@ -85,11 +148,26 @@ public class Accounts extends ListActivity implements OnItemClickListener, OnCli
        super.onResume();

        refresh();
        MessagingController.getInstance(getApplication()).addListener(mListener);
    }
    
    @Override
    public void onPause()
    {
      super.onPause();
      MessagingController.getInstance(getApplication()).removeListener(mListener);
    }

    private void refresh() {
        Account[] accounts = Preferences.getPreferences(this).getAccounts();
        getListView().setAdapter(new AccountsAdapter(accounts));
        mAdapter = new AccountsAdapter(accounts);
        getListView().setAdapter(mAdapter);
        
        for (Account account : accounts)
        {
          MessagingController.getInstance(getApplication()).getAccountUnreadCount(Accounts.this, account, mListener);
        }
        
    }

    private void onAddNewAccount() {
@@ -329,18 +407,19 @@ getPackageManager().getPackageInfo(getPackageName(), 0);
            if (account.getEmail().equals(account.getDescription())) {
                holder.email.setVisibility(View.GONE);
            }
            int unreadMessageCount = 0;
            try {
            	unreadMessageCount = account.getUnreadMessageCount(Accounts.this, getApplication());
            }
            catch (MessagingException me) {
                /*
                 * This is not expected to fail under normal circumstances.
                 */
                throw new RuntimeException("Unable to get unread count from local store.", me);
            }

            Integer unreadMessageCount = unreadMessageCounts.get(account.getUuid());
            if (unreadMessageCount != null)
            {
              holder.newMessageCount.setText(Integer.toString(unreadMessageCount));
              holder.newMessageCount.setVisibility(unreadMessageCount > 0 ? View.VISIBLE : View.GONE);
            }
            else
            {
              //holder.newMessageCount.setText("-");
              holder.newMessageCount.setVisibility(View.GONE); 
            }
            
            return view;
        }