Clear references to inner classes in onDestroy().
Also - Made inner classes private if possible. - Made some members final. Bug 2570603 Change-Id: I34451000f2540c67e1039ea9dc4839dbec5ffab7
This commit is contained in:
parent
c94c077a66
commit
59cf1d05c1
|
@ -31,6 +31,7 @@ import android.content.Context;
|
|||
import android.content.res.TypedArray;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.AsyncTask;
|
||||
import android.text.Editable;
|
||||
import android.util.Base64;
|
||||
import android.widget.TextView;
|
||||
|
@ -506,4 +507,24 @@ public class Utility {
|
|||
public static String replaceBareLfWithCrlf(String str) {
|
||||
return str.replace("\r", "").replace("\n", "\r\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel an {@link AsyncTask}. If it's already running, it'll be interrupted.
|
||||
*/
|
||||
public static void cancelTaskInterrupt(AsyncTask<?, ?, ?> task) {
|
||||
cancelTask(task, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel an {@link AsyncTask}.
|
||||
*
|
||||
* @param mayInterruptIfRunning <tt>true</tt> if the thread executing this
|
||||
* task should be interrupted; otherwise, in-progress tasks are allowed
|
||||
* to complete.
|
||||
*/
|
||||
public static void cancelTask(AsyncTask<?, ?, ?> task, boolean mayInterruptIfRunning) {
|
||||
if (task != null && task.getStatus() != AsyncTask.Status.FINISHED) {
|
||||
task.cancel(mayInterruptIfRunning);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -91,9 +91,8 @@ public class AccountFolderList extends ListActivity implements OnItemClickListen
|
|||
|
||||
private LoadAccountsTask mLoadAccountsTask;
|
||||
private DeleteAccountTask mDeleteAccountTask;
|
||||
|
||||
private MessageListHandler mHandler = new MessageListHandler();
|
||||
private ControllerResults mControllerCallback = new ControllerResults();
|
||||
private MessageListHandler mHandler;
|
||||
private ControllerResults mControllerCallback;
|
||||
|
||||
/**
|
||||
* Reduced mailbox projection used by AccountsAdapter
|
||||
|
@ -154,6 +153,8 @@ public class AccountFolderList extends ListActivity implements OnItemClickListen
|
|||
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE,
|
||||
R.layout.list_title);
|
||||
|
||||
mHandler = new MessageListHandler();
|
||||
mControllerCallback = new ControllerResults();
|
||||
mProgressIcon = (ProgressBar) findViewById(R.id.title_progress_icon);
|
||||
|
||||
mListView = getListView();
|
||||
|
@ -203,19 +204,21 @@ public class AccountFolderList extends ListActivity implements OnItemClickListen
|
|||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
Utility.cancelTaskInterrupt(mLoadAccountsTask);
|
||||
mLoadAccountsTask = null;
|
||||
|
||||
if (mLoadAccountsTask != null &&
|
||||
mLoadAccountsTask.getStatus() != LoadAccountsTask.Status.FINISHED) {
|
||||
mLoadAccountsTask.cancel(true);
|
||||
mLoadAccountsTask = null;
|
||||
}
|
||||
if (mDeleteAccountTask != null &&
|
||||
mDeleteAccountTask.getStatus() != DeleteAccountTask.Status.FINISHED) {
|
||||
mDeleteAccountTask.cancel(false); // false == allow the cancel to run to completion
|
||||
mDeleteAccountTask = null;
|
||||
}
|
||||
// TODO: We shouldn't call cancel() for DeleteAccountTask. If the task hasn't
|
||||
// started, this will mark it as "don't run", but we always want it to finish.
|
||||
// (But don't just remove this cancel() call. DeleteAccountTask.onPostExecute() checks if
|
||||
// it's been canceled to decided whether to update the UI.)
|
||||
Utility.cancelTask(mDeleteAccountTask, false); // Don't interrupt if it's running.
|
||||
mDeleteAccountTask = null;
|
||||
|
||||
mListAdapter.changeCursor(null);
|
||||
mListAdapter = null;
|
||||
|
||||
mHandler = null;
|
||||
mControllerCallback = null;
|
||||
}
|
||||
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
|
@ -357,8 +360,8 @@ public class AccountFolderList extends ListActivity implements OnItemClickListen
|
|||
}
|
||||
|
||||
private class DeleteAccountTask extends AsyncTask<Void, Void, Void> {
|
||||
private long mAccountId;
|
||||
private String mAccountUri;
|
||||
private final long mAccountId;
|
||||
private final String mAccountUri;
|
||||
|
||||
public DeleteAccountTask(long accountId, String accountUri) {
|
||||
mAccountId = accountId;
|
||||
|
@ -395,10 +398,7 @@ public class AccountFolderList extends ListActivity implements OnItemClickListen
|
|||
}
|
||||
|
||||
private void updateAccounts() {
|
||||
if (mLoadAccountsTask != null &&
|
||||
mLoadAccountsTask.getStatus() != LoadAccountsTask.Status.FINISHED) {
|
||||
mLoadAccountsTask.cancel(true);
|
||||
}
|
||||
Utility.cancelTaskInterrupt(mLoadAccountsTask);
|
||||
mLoadAccountsTask = (LoadAccountsTask) new LoadAccountsTask().execute();
|
||||
}
|
||||
|
||||
|
@ -468,6 +468,7 @@ public class AccountFolderList extends ListActivity implements OnItemClickListen
|
|||
int numAccounts = EmailContent.count(AccountFolderList.this,
|
||||
Account.CONTENT_URI, null, null);
|
||||
mListAdapter.addOnDeletingAccount(mSelectedContextAccount.mId);
|
||||
|
||||
mDeleteAccountTask = (DeleteAccountTask) new DeleteAccountTask(
|
||||
mSelectedContextAccount.mId,
|
||||
mSelectedContextAccount.getStoreUri(AccountFolderList.this)).execute();
|
||||
|
@ -603,7 +604,7 @@ public class AccountFolderList extends ListActivity implements OnItemClickListen
|
|||
/**
|
||||
* Handler for UI-thread operations (when called from callbacks or any other threads)
|
||||
*/
|
||||
class MessageListHandler extends Handler {
|
||||
private class MessageListHandler extends Handler {
|
||||
private static final int MSG_PROGRESS = 1;
|
||||
|
||||
@Override
|
||||
|
@ -685,12 +686,12 @@ public class AccountFolderList extends ListActivity implements OnItemClickListen
|
|||
|
||||
/* package */ static class AccountsAdapter extends CursorAdapter {
|
||||
|
||||
Context mContext;
|
||||
private LayoutInflater mInflater;
|
||||
private int mMailboxesCount;
|
||||
private int mSeparatorPosition;
|
||||
long mDefaultAccountId;
|
||||
ArrayList<Long> mOnDeletingAccounts = new ArrayList<Long>();
|
||||
private final Context mContext;
|
||||
private final LayoutInflater mInflater;
|
||||
private final int mMailboxesCount;
|
||||
private final int mSeparatorPosition;
|
||||
private final long mDefaultAccountId;
|
||||
private final ArrayList<Long> mOnDeletingAccounts = new ArrayList<Long>();
|
||||
|
||||
public static AccountsAdapter getInstance(Cursor mailboxesCursor, Cursor accountsCursor,
|
||||
Context context, long defaultAccountId) {
|
||||
|
|
|
@ -77,8 +77,8 @@ public class MailboxList extends ListActivity implements OnItemClickListener, On
|
|||
private TextView mErrorBanner;
|
||||
|
||||
private MailboxListAdapter mListAdapter;
|
||||
private MailboxListHandler mHandler = new MailboxListHandler();
|
||||
private ControllerResults mControllerCallback = new ControllerResults();
|
||||
private MailboxListHandler mHandler;
|
||||
private ControllerResults mControllerCallback;
|
||||
|
||||
// DB access
|
||||
private long mAccountId;
|
||||
|
@ -109,6 +109,8 @@ public class MailboxList extends ListActivity implements OnItemClickListener, On
|
|||
super.onCreate(icicle);
|
||||
setContentView(R.layout.mailbox_list);
|
||||
|
||||
mHandler = new MailboxListHandler();
|
||||
mControllerCallback = new ControllerResults();
|
||||
mListView = getListView();
|
||||
mProgressIcon = (ProgressBar) findViewById(R.id.title_progress_icon);
|
||||
mErrorBanner = (TextView) findViewById(R.id.connection_error_text);
|
||||
|
@ -189,22 +191,17 @@ public class MailboxList extends ListActivity implements OnItemClickListener, On
|
|||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
|
||||
if (mLoadMailboxesTask != null &&
|
||||
mLoadMailboxesTask.getStatus() != LoadMailboxesTask.Status.FINISHED) {
|
||||
mLoadMailboxesTask.cancel(true);
|
||||
mLoadMailboxesTask = null;
|
||||
}
|
||||
if (mLoadAccountNameTask != null &&
|
||||
mLoadAccountNameTask.getStatus() != LoadMailboxesTask.Status.FINISHED) {
|
||||
mLoadAccountNameTask.cancel(true);
|
||||
mLoadAccountNameTask = null;
|
||||
}
|
||||
if (mMessageCountTask != null &&
|
||||
mMessageCountTask.getStatus() != MessageCountTask.Status.FINISHED) {
|
||||
mMessageCountTask.cancel(true);
|
||||
mMessageCountTask = null;
|
||||
}
|
||||
Utility.cancelTaskInterrupt(mLoadMailboxesTask);
|
||||
mLoadMailboxesTask = null;
|
||||
Utility.cancelTaskInterrupt(mLoadAccountNameTask);
|
||||
mLoadAccountNameTask = null;
|
||||
Utility.cancelTaskInterrupt(mMessageCountTask);
|
||||
mMessageCountTask = null;
|
||||
|
||||
mListAdapter.changeCursor(null);
|
||||
mListAdapter = null;
|
||||
mHandler = null;
|
||||
mControllerCallback = null;
|
||||
}
|
||||
|
||||
public void onClick(View v) {
|
||||
|
|
|
@ -150,7 +150,7 @@ public class MessageCompose extends Activity implements OnClickListener, OnFocus
|
|||
private TextView mRightTitle;
|
||||
|
||||
private Controller mController;
|
||||
private Listener mListener = new Listener();
|
||||
private Listener mListener;
|
||||
private boolean mDraftNeedsSaving;
|
||||
private boolean mMessageLoaded;
|
||||
private AsyncTask mLoadAttachmentsTask;
|
||||
|
@ -295,6 +295,7 @@ public class MessageCompose extends Activity implements OnClickListener, OnFocus
|
|||
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.list_title);
|
||||
|
||||
mController = Controller.getInstance(getApplication());
|
||||
mListener = new Listener();
|
||||
initViews();
|
||||
setDraftNeedsSaving(false);
|
||||
|
||||
|
@ -376,12 +377,6 @@ public class MessageCompose extends Activity implements OnClickListener, OnFocus
|
|||
mController.removeResultCallback(mListener);
|
||||
}
|
||||
|
||||
private static void cancelTask(AsyncTask<?, ?, ?> task) {
|
||||
if (task != null && task.getStatus() != AsyncTask.Status.FINISHED) {
|
||||
task.cancel(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* We override onDestroy to make sure that the WebView gets explicitly destroyed.
|
||||
* Otherwise it can leak native references.
|
||||
|
@ -391,22 +386,28 @@ public class MessageCompose extends Activity implements OnClickListener, OnFocus
|
|||
super.onDestroy();
|
||||
mQuotedText.destroy();
|
||||
mQuotedText = null;
|
||||
cancelTask(mLoadAttachmentsTask);
|
||||
|
||||
Utility.cancelTaskInterrupt(mLoadAttachmentsTask);
|
||||
mLoadAttachmentsTask = null;
|
||||
cancelTask(mLoadMessageTask);
|
||||
Utility.cancelTaskInterrupt(mLoadMessageTask);
|
||||
mLoadMessageTask = null;
|
||||
// don't cancel mSaveMessageTask, let it do its job to the end.
|
||||
mSaveMessageTask = null;
|
||||
|
||||
// TODO Make sure the three adapters don't leak their internal cursors
|
||||
if (mAddressAdapterTo != null) {
|
||||
mAddressAdapterTo.changeCursor(null);
|
||||
mAddressAdapterTo = null;
|
||||
}
|
||||
if (mAddressAdapterCc != null) {
|
||||
mAddressAdapterCc.changeCursor(null);
|
||||
mAddressAdapterCc = null;
|
||||
}
|
||||
if (mAddressAdapterBcc != null) {
|
||||
mAddressAdapterBcc.changeCursor(null);
|
||||
mAddressAdapterBcc = null;
|
||||
}
|
||||
mHandler = null;
|
||||
mListener = null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1544,7 +1545,7 @@ public class MessageCompose extends Activity implements OnClickListener, OnFocus
|
|||
}
|
||||
}
|
||||
|
||||
class Listener implements Controller.Result {
|
||||
private class Listener implements Controller.Result {
|
||||
public void updateMailboxListCallback(MessagingException result, long accountId,
|
||||
int progress) {
|
||||
}
|
||||
|
|
|
@ -110,9 +110,10 @@ public class MessageList extends ListActivity implements OnItemClickListener, On
|
|||
private int mListFooterMode;
|
||||
|
||||
private MessageListAdapter mListAdapter;
|
||||
private MessageListHandler mHandler = new MessageListHandler();
|
||||
private Controller mController = Controller.getInstance(getApplication());
|
||||
private ControllerResults mControllerCallback = new ControllerResults();
|
||||
private MessageListHandler mHandler;
|
||||
private final Controller mController = Controller.getInstance(getApplication());
|
||||
private ControllerResults mControllerCallback;
|
||||
|
||||
private TextView mLeftTitle;
|
||||
private ProgressBar mProgressIcon;
|
||||
|
||||
|
@ -228,6 +229,8 @@ public class MessageList extends ListActivity implements OnItemClickListener, On
|
|||
super.onCreate(icicle);
|
||||
setContentView(R.layout.message_list);
|
||||
|
||||
mHandler = new MessageListHandler();
|
||||
mControllerCallback = new ControllerResults();
|
||||
mCanAutoRefresh = true;
|
||||
mListView = getListView();
|
||||
mMultiSelectPanel = findViewById(R.id.footer_organize);
|
||||
|
@ -315,28 +318,19 @@ public class MessageList extends ListActivity implements OnItemClickListener, On
|
|||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
|
||||
if (mLoadMessagesTask != null &&
|
||||
mLoadMessagesTask.getStatus() != LoadMessagesTask.Status.FINISHED) {
|
||||
mLoadMessagesTask.cancel(true);
|
||||
mLoadMessagesTask = null;
|
||||
}
|
||||
if (mFindMailboxTask != null &&
|
||||
mFindMailboxTask.getStatus() != FindMailboxTask.Status.FINISHED) {
|
||||
mFindMailboxTask.cancel(true);
|
||||
mFindMailboxTask = null;
|
||||
}
|
||||
if (mSetTitleTask != null &&
|
||||
mSetTitleTask.getStatus() != SetTitleTask.Status.FINISHED) {
|
||||
mSetTitleTask.cancel(true);
|
||||
mSetTitleTask = null;
|
||||
}
|
||||
if (mSetFooterTask != null &&
|
||||
mSetFooterTask.getStatus() != SetTitleTask.Status.FINISHED) {
|
||||
mSetFooterTask.cancel(true);
|
||||
mSetFooterTask = null;
|
||||
}
|
||||
Utility.cancelTaskInterrupt(mLoadMessagesTask);
|
||||
mLoadMessagesTask = null;
|
||||
Utility.cancelTaskInterrupt(mFindMailboxTask);
|
||||
mFindMailboxTask = null;
|
||||
Utility.cancelTaskInterrupt(mSetTitleTask);
|
||||
mSetTitleTask = null;
|
||||
Utility.cancelTaskInterrupt(mSetFooterTask);
|
||||
mSetFooterTask = null;
|
||||
|
||||
mListAdapter.changeCursor(null);
|
||||
mListAdapter = null;
|
||||
mHandler = null;
|
||||
mControllerCallback = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -156,9 +156,9 @@ public class MessageView extends Activity implements OnClickListener {
|
|||
private Drawable mFavoriteIconOn;
|
||||
private Drawable mFavoriteIconOff;
|
||||
|
||||
private MessageViewHandler mHandler = new MessageViewHandler();
|
||||
private MessageViewHandler mHandler;
|
||||
private Controller mController;
|
||||
private ControllerResults mControllerCallback = new ControllerResults();
|
||||
private ControllerResults mControllerCallback;
|
||||
|
||||
private View mMoveToNewer;
|
||||
private View mMoveToOlder;
|
||||
|
@ -176,7 +176,7 @@ public class MessageView extends Activity implements OnClickListener {
|
|||
// this is true when reply & forward are disabled, such as messages in the trash
|
||||
private boolean mDisableReplyAndForward;
|
||||
|
||||
class MessageViewHandler extends Handler {
|
||||
private class MessageViewHandler extends Handler {
|
||||
private static final int MSG_PROGRESS = 1;
|
||||
private static final int MSG_ATTACHMENT_PROGRESS = 2;
|
||||
private static final int MSG_LOAD_CONTENT_URI = 3;
|
||||
|
@ -346,6 +346,9 @@ public class MessageView extends Activity implements OnClickListener {
|
|||
super.onCreate(icicle);
|
||||
setContentView(R.layout.message_view);
|
||||
|
||||
mHandler = new MessageViewHandler();
|
||||
mControllerCallback = new ControllerResults();
|
||||
|
||||
mSubjectView = (TextView) findViewById(R.id.subject);
|
||||
mFromView = (TextView) findViewById(R.id.from);
|
||||
mToView = (TextView) findViewById(R.id.to);
|
||||
|
@ -472,22 +475,16 @@ public class MessageView extends Activity implements OnClickListener {
|
|||
}
|
||||
}
|
||||
|
||||
private static void cancelTask(AsyncTask<?, ?, ?> task) {
|
||||
if (task != null && task.getStatus() != AsyncTask.Status.FINISHED) {
|
||||
task.cancel(true);
|
||||
}
|
||||
}
|
||||
|
||||
private void cancelAllTasks() {
|
||||
cancelTask(mLoadMessageTask);
|
||||
Utility.cancelTaskInterrupt(mLoadMessageTask);
|
||||
mLoadMessageTask = null;
|
||||
cancelTask(mLoadBodyTask);
|
||||
Utility.cancelTaskInterrupt(mLoadBodyTask);
|
||||
mLoadBodyTask = null;
|
||||
cancelTask(mLoadAttachmentsTask);
|
||||
Utility.cancelTaskInterrupt(mLoadAttachmentsTask);
|
||||
mLoadAttachmentsTask = null;
|
||||
cancelTask(mLoadMessageListTask);
|
||||
Utility.cancelTaskInterrupt(mLoadMessageListTask);
|
||||
mLoadMessageListTask = null;
|
||||
cancelTask(mPresenceCheckTask);
|
||||
Utility.cancelTaskInterrupt(mPresenceCheckTask);
|
||||
mPresenceCheckTask = null;
|
||||
}
|
||||
|
||||
|
@ -505,6 +502,9 @@ public class MessageView extends Activity implements OnClickListener {
|
|||
mMessageContentView = null;
|
||||
}
|
||||
// the cursor was closed in onPause()
|
||||
|
||||
mHandler = null;
|
||||
mControllerCallback = null;
|
||||
}
|
||||
|
||||
private void onDelete() {
|
||||
|
@ -1433,7 +1433,7 @@ public class MessageView extends Activity implements OnClickListener {
|
|||
/**
|
||||
* Controller results listener. This completely replaces MessagingListener
|
||||
*/
|
||||
class ControllerResults implements Controller.Result {
|
||||
private class ControllerResults implements Controller.Result {
|
||||
|
||||
public void loadMessageForViewCallback(MessagingException result, long messageId,
|
||||
int progress) {
|
||||
|
@ -1662,7 +1662,7 @@ public class MessageView extends Activity implements OnClickListener {
|
|||
private Context mContext;
|
||||
private MediaScannerConnection mConnection;
|
||||
private File mFile;
|
||||
MessageViewHandler mHandler;
|
||||
private MessageViewHandler mHandler;
|
||||
|
||||
public MediaScannerNotifier(Context context, File file, MessageViewHandler handler) {
|
||||
mContext = context;
|
||||
|
|
|
@ -21,6 +21,7 @@ import com.android.email.Email;
|
|||
import com.android.email.LegacyConversions;
|
||||
import com.android.email.Preferences;
|
||||
import com.android.email.R;
|
||||
import com.android.email.Utility;
|
||||
import com.android.email.activity.setup.AccountSettingsUtils;
|
||||
import com.android.email.activity.setup.AccountSettingsUtils.Provider;
|
||||
import com.android.email.mail.FetchProfile;
|
||||
|
@ -134,11 +135,8 @@ public class UpgradeAccounts extends ListActivity implements OnClickListener {
|
|||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
|
||||
if (mConversionTask != null &&
|
||||
mConversionTask.getStatus() != ConversionTask.Status.FINISHED) {
|
||||
mConversionTask.cancel(false);
|
||||
mConversionTask = null;
|
||||
}
|
||||
Utility.cancelTask(mConversionTask, false); // false = Don't interrupt running task
|
||||
mConversionTask = null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -16,16 +16,13 @@
|
|||
|
||||
package com.android.email.activity;
|
||||
|
||||
import com.android.email.Account;
|
||||
import com.android.email.AccountBackupRestore;
|
||||
import com.android.email.ExchangeUtils;
|
||||
import com.android.email.Preferences;
|
||||
import com.android.email.activity.setup.AccountSetupBasics;
|
||||
import com.android.email.provider.EmailContent;
|
||||
import com.android.email.provider.EmailContent.Mailbox;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.os.Bundle;
|
||||
|
|
Loading…
Reference in New Issue