Fix NPE in MessageViewFragment

Call clearContent() in onDestroy(), instead of cancelAllTasks().
(This is what I thought I was doing.)

Calling clearContent() tells the BG thread that the activity has already
been destroyed, and prevents them from loading a message.

Also as a precaution, don't load a message if getActivity() returns null,
which means the activity has already been destroyed.

Bug 3134403

Change-Id: I0d591e0dd147f73e70b0c027dc8037482197f7b4
This commit is contained in:
Makoto Onuki 2010-11-22 14:04:04 -08:00
parent 79c5d35c13
commit deda053f7c
3 changed files with 20 additions and 8 deletions

View File

@ -110,9 +110,8 @@ public class MessageFileViewFragment extends MessageViewFragmentBase {
* NOTE See the comment on the super method. It's called on a worker thread.
*/
@Override
protected Message openMessageSync() {
protected Message openMessageSync(Activity activity) {
synchronized (mLock) {
final Activity activity = getActivity();
Uri messageUri = mFileEmailUri;
if (messageUri == null) {
return null; // Called after clearContent().

View File

@ -25,6 +25,7 @@ import com.android.email.provider.EmailContent.Mailbox;
import com.android.email.provider.EmailContent.Message;
import com.android.email.service.EmailServiceConstants;
import android.app.Activity;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
@ -254,13 +255,13 @@ public class MessageViewFragment extends MessageViewFragmentBase {
* NOTE See the comment on the super method. It's called on a worker thread.
*/
@Override
protected Message openMessageSync() {
protected Message openMessageSync(Activity activity) {
synchronized (mLock) {
long messageId = mMessageIdToOpen;
if (messageId < 0) {
return null; // Called after clearContent().
}
return Message.restoreMessageWithId(getActivity(), messageId);
return Message.restoreMessageWithId(activity, messageId);
}
}

View File

@ -36,6 +36,7 @@ import com.android.email.service.AttachmentDownloadService;
import org.apache.commons.io.IOUtils;
import android.app.Activity;
import android.app.Fragment;
import android.app.LoaderManager.LoaderCallbacks;
import android.content.ActivityNotFoundException;
@ -394,7 +395,7 @@ public abstract class MessageViewFragmentBase extends Fragment implements View.O
}
mCallback.onMessageViewGone();
mController.removeResultCallback(mControllerCallback);
cancelAllTasks();
clearContent();
mMessageContentView.destroy();
mMessageContentView = null;
super.onDestroy();
@ -837,8 +838,10 @@ public abstract class MessageViewFragmentBase extends Fragment implements View.O
* NOTE This method is called on a worker thread! Implementations must properly synchronize
* when accessing members. This method may be called after or even at the same time as
* {@link #clearContent()}.
*
* @param activity the parent activity. Subclass use it as a context, and to show a toast.
*/
protected abstract Message openMessageSync();
protected abstract Message openMessageSync(Activity activity);
/**
* Async task for loading a single message outside of the UI thread
@ -857,7 +860,11 @@ public abstract class MessageViewFragmentBase extends Fragment implements View.O
@Override
protected Message doInBackground(Void... params) {
Message message = openMessageSync();
Activity activity = getActivity();
Message message = null;
if (activity != null) {
message = openMessageSync(activity);
}
if (message != null) {
mMailboxType = Mailbox.getMailboxType(mContext, message.mMailboxKey);
if (mMailboxType == -1) {
@ -893,7 +900,12 @@ public abstract class MessageViewFragmentBase extends Fragment implements View.O
if (!isMessageSpecified()) { // just in case
return null;
}
return openMessageSync();
Activity activity = getActivity();
if (activity == null) {
return null;
} else {
return openMessageSync(activity);
}
}
@Override