diff options
author | Dianne Hackborn <hackbod@google.com> | 2011-03-01 16:40:54 -0800 |
---|---|---|
committer | Dianne Hackborn <hackbod@google.com> | 2011-03-01 17:20:43 -0800 |
commit | bfe2e3f9da507a19f5602f0b267be92ddccdd250 (patch) | |
tree | 8501a8e783f305bebc2366fabcdc08f40704a6c3 /core/java/android | |
parent | 6c2193a7e26c0794f45dfb60d2a0cf6ae776f390 (diff) | |
download | frameworks_base-bfe2e3f9da507a19f5602f0b267be92ddccdd250.zip frameworks_base-bfe2e3f9da507a19f5602f0b267be92ddccdd250.tar.gz frameworks_base-bfe2e3f9da507a19f5602f0b267be92ddccdd250.tar.bz2 |
Fix issue #3405957 com.android.settings: java.lang.NullPointerException...
...at android.app.DialogFragment.dismissInternal(DialogFragment.java:264)
Don't allow a DialogFragment to be dismissed twice.
Change-Id: Id2e9e3be1046b0d7862492c57c36001d8fd44a69
Diffstat (limited to 'core/java/android')
-rw-r--r-- | core/java/android/app/DialogFragment.java | 65 |
1 files changed, 56 insertions, 9 deletions
diff --git a/core/java/android/app/DialogFragment.java b/core/java/android/app/DialogFragment.java index 50953d7..3d99055 100644 --- a/core/java/android/app/DialogFragment.java +++ b/core/java/android/app/DialogFragment.java @@ -25,6 +25,9 @@ import android.view.ViewGroup; import android.view.Window; import android.view.WindowManager; +import java.io.FileDescriptor; +import java.io.PrintWriter; + /** * A fragment that displays a dialog window, floating on top of its * activity's window. This fragment contains a Dialog object, which it @@ -177,8 +180,9 @@ public class DialogFragment extends Fragment int mBackStackId = -1; Dialog mDialog; - boolean mDestroyed; - boolean mRemoved; + boolean mViewDestroyed; + boolean mDismissed; + boolean mShownByMe; public DialogFragment() { } @@ -219,6 +223,8 @@ public class DialogFragment extends Fragment * {@link FragmentTransaction#add(Fragment, String) FragmentTransaction.add}. */ public void show(FragmentManager manager, String tag) { + mDismissed = false; + mShownByMe = true; FragmentTransaction ft = manager.beginTransaction(); ft.add(this, tag); ft.commit(); @@ -234,8 +240,10 @@ public class DialogFragment extends Fragment * {@link FragmentTransaction#commit() FragmentTransaction.commit()}. */ public int show(FragmentTransaction transaction, String tag) { + mDismissed = false; + mShownByMe = true; transaction.add(this, tag); - mRemoved = false; + mViewDestroyed = false; mBackStackId = transaction.commit(); return mBackStackId; } @@ -251,11 +259,16 @@ public class DialogFragment extends Fragment } void dismissInternal(boolean allowStateLoss) { + if (mDismissed) { + return; + } + mDismissed = true; + mShownByMe = false; if (mDialog != null) { mDialog.dismiss(); mDialog = null; } - mRemoved = true; + mViewDestroyed = true; if (mBackStackId >= 0) { getFragmentManager().popBackStack(mBackStackId, FragmentManager.POP_BACK_STACK_INCLUSIVE); @@ -329,6 +342,27 @@ public class DialogFragment extends Fragment } @Override + public void onAttach(Activity activity) { + super.onAttach(activity); + if (!mShownByMe) { + // If not explicitly shown through our API, take this as an + // indication that the dialog is no longer dismissed. + mDismissed = false; + } + } + + @Override + public void onDetach() { + super.onDetach(); + if (!mShownByMe && !mDismissed) { + // The fragment was not shown by a direct call here, it is not + // dismissed, and now it is being detached... well, okay, thou + // art now dismissed. Have fun. + mDismissed = true; + } + } + + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -352,7 +386,6 @@ public class DialogFragment extends Fragment } mDialog = onCreateDialog(savedInstanceState); - mDestroyed = false; switch (mStyle) { case STYLE_NO_INPUT: mDialog.getWindow().addFlags( @@ -397,7 +430,7 @@ public class DialogFragment extends Fragment } public void onDismiss(DialogInterface dialog) { - if (!mRemoved) { + if (!mViewDestroyed) { // Note: we need to use allowStateLoss, because the dialog // dispatches this asynchronously so we can receive the call // after the activity is paused. Worst case, when the user comes @@ -439,7 +472,7 @@ public class DialogFragment extends Fragment public void onStart() { super.onStart(); if (mDialog != null) { - mRemoved = false; + mViewDestroyed = false; mDialog.show(); } } @@ -484,14 +517,28 @@ public class DialogFragment extends Fragment @Override public void onDestroyView() { super.onDestroyView(); - mDestroyed = true; if (mDialog != null) { // Set removed here because this dismissal is just to hide // the dialog -- we don't want this to cause the fragment to // actually be removed. - mRemoved = true; + mViewDestroyed = true; mDialog.dismiss(); mDialog = null; } } + + @Override + public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) { + super.dump(prefix, fd, writer, args); + writer.print(prefix); writer.println("DialogFragment:"); + writer.print(prefix); writer.print(" mStyle="); writer.print(mStyle); + writer.print(" mTheme=0x"); writer.println(Integer.toHexString(mTheme)); + writer.print(prefix); writer.print(" mCancelable="); writer.print(mCancelable); + writer.print(" mShowsDialog="); writer.print(mShowsDialog); + writer.print(" mBackStackId="); writer.println(mBackStackId); + writer.print(prefix); writer.print(" mDialog="); writer.println(mDialog); + writer.print(prefix); writer.print(" mViewDestroyed="); writer.print(mViewDestroyed); + writer.print(" mDismissed="); writer.print(mDismissed); + writer.print(" mShownByMe="); writer.println(mShownByMe); + } } |