Prevent wasteful calls to invalidateOptionsMenu

The app is spending a lot of time in startup inflating XML. I suspect a
lot of it is due to the refreshActionBar() calls.

On a normal startup with NO refresh, the action bar was rebuilt 6 times.
If a refresh happens, the refresh callbacks get called in rapid
succession (20+ successive calls is not uncommon), which seemed really
wasteful.

Change-Id: I05feb56ba7fafb109d820328f591526945ca0a5f
This commit is contained in:
Ben Komalo 2011-07-05 13:59:39 -04:00
parent d8ab562d0d
commit 33d6307d4b
2 changed files with 47 additions and 21 deletions

View File

@ -1145,8 +1145,10 @@ public class MessageListFragment extends ListFragment
}
private void showSendCommand(boolean show) {
mShowSendCommand = show;
mActivity.invalidateOptionsMenu();
if (show != mShowSendCommand) {
mShowSendCommand = show;
mActivity.invalidateOptionsMenu();
}
}
private void showSendCommandIfNecessary() {
@ -1247,25 +1249,28 @@ public class MessageListFragment extends ListFragment
}
// If this is a search mailbox, set the query; otherwise, clear it
if (mMailbox != null && mMailbox.mType == Mailbox.TYPE_SEARCH) {
mListAdapter.setQuery(getListContext().getSearchParams().mFilter);
mSearchedMailbox = ((SearchResultsCursor) c).getSearchedMailbox();
} else {
mListAdapter.setQuery(null);
mSearchedMailbox = null;
if (mIsFirstLoad) {
if (mMailbox != null && mMailbox.mType == Mailbox.TYPE_SEARCH) {
mListAdapter.setQuery(getListContext().getSearchParams().mFilter);
mSearchedMailbox = ((SearchResultsCursor) c).getSearchedMailbox();
} else {
mListAdapter.setQuery(null);
mSearchedMailbox = null;
}
showSendCommandIfNecessary();
// Show chips if combined view.
mListAdapter.setShowColorChips(isCombinedMailbox() && mCountTotalAccounts > 1);
}
// Update the list
mListAdapter.swapCursor(cursor);
// Show chips if combined view.
mListAdapter.setShowColorChips(isCombinedMailbox() && mCountTotalAccounts > 1);
// Various post processing...
updateSearchHeader(cursor);
autoRefreshStaleMailbox();
addFooterView();
updateSelectionMode();
showSendCommandIfNecessary();
showNoMessageText((cursor.getCount() == 0)
&& (getListContext().isSearch() || (mListFooterMode == LIST_FOOTER_MODE_NONE)));

View File

@ -101,19 +101,39 @@ abstract class UIControllerBase implements MailboxListFragment.Callback,
*/
protected MessageListContext mListContext;
private final RefreshManager.Listener mRefreshListener
= new RefreshManager.Listener() {
private class RefreshListener implements RefreshManager.Listener {
private MenuItem mRefreshIcon;
@Override
public void onMessagingError(final long accountId, long mailboxId, final String message) {
refreshActionBar();
updateRefreshIcon();
}
@Override
public void onRefreshStatusChanged(long accountId, long mailboxId) {
refreshActionBar();
updateRefreshIcon();
}
void setRefreshIcon(MenuItem icon) {
mRefreshIcon = icon;
updateRefreshIcon();
}
private void updateRefreshIcon() {
if (mRefreshIcon == null) {
return;
}
if (isRefreshInProgress()) {
mRefreshIcon.setActionView(R.layout.action_bar_indeterminate_progress);
} else {
mRefreshIcon.setActionView(null);
}
}
};
private final RefreshListener mRefreshListener = new RefreshListener();
public UIControllerBase(EmailActivity activity) {
mActivity = activity;
mFragmentManager = activity.getFragmentManager();
@ -277,6 +297,11 @@ abstract class UIControllerBase implements MailboxListFragment.Callback,
protected void installMailboxListFragment(MailboxListFragment fragment) {
mMailboxListFragment = fragment;
mMailboxListFragment.setCallback(this);
// TODO: consolidate this refresh with the one that the Fragment itself does. since
// the fragment calls setHasOptionsMenu(true) - it invalidates when it gets attached.
// However the timing is slightly different and leads to a delay in update if this isn't
// here - investigate why. same for the other installs.
refreshActionBar();
}
@ -704,18 +729,14 @@ abstract class UIControllerBase implements MailboxListFragment.Callback,
* Handles the {@link android.app.Activity#onPrepareOptionsMenu} callback.
*/
public boolean onPrepareOptionsMenu(MenuInflater inflater, Menu menu) {
// Update the refresh button.
MenuItem item = menu.findItem(R.id.refresh);
if (isRefreshEnabled()) {
item.setVisible(true);
if (isRefreshInProgress()) {
item.setActionView(R.layout.action_bar_indeterminate_progress);
} else {
item.setActionView(null);
}
mRefreshListener.setRefreshIcon(item);
} else {
item.setVisible(false);
mRefreshListener.setRefreshIcon(null);
}
// Deal with protocol-specific menu options.