diff options
| author | Dianne Hackborn <hackbod@google.com> | 2010-09-11 20:52:31 -0700 |
|---|---|---|
| committer | Dianne Hackborn <hackbod@google.com> | 2010-09-12 17:10:04 -0700 |
| commit | 3e449ce00ed2d3b271e50bc7a52798f630973bf1 (patch) | |
| tree | 94038ccfea9e3412b770b3478853e7f83129c9b5 | |
| parent | 2f761760459fe27c8e9f96569bb7f28fc5b58bab (diff) | |
| download | frameworks_base-3e449ce00ed2d3b271e50bc7a52798f630973bf1.zip frameworks_base-3e449ce00ed2d3b271e50bc7a52798f630973bf1.tar.gz frameworks_base-3e449ce00ed2d3b271e50bc7a52798f630973bf1.tar.bz2 | |
Some fragment stuff:
Fix issue #2975886: Make getTargetFragment() survive rotation events with
retained fragments. We now fix up the fragment pointer when restoring state.
Fix issue #2919928: In PreferenceFragment, addPreferencesFromResources() is
not effective when called after onActivityCreated(). Note to self: do not use
a what code of 0. Maybe that should be documented (I'll do it in gingerbread).
Hopefully implement #2992753: DialogFragment.dismiss will NPE if called too soon
(before attached to activity). We now keep track of the FragmentManager
separately from the activity, and set that as soon as the fragment is part of a
transaction.
Investigate issue #2988876: NPE when device orientation is changed. The NPE is
because of the app trying to do a fragment transaction in onPause(). This is
fundamentally not viable, since (a) the activity will be gone before we ever
have a chance to process the message to commit the transaction, and (b) even if
we did try to commit the transaction earlier, this would be done after
onSaveInstanceState() and thus not work in cases where the activity gets killed
in the background. So instead, we'll just throw an immediate exception if you
try to do this.
Change-Id: Iea62b50eb79f066af2471fce86836d073398f4f7
| -rw-r--r-- | core/java/android/app/Activity.java | 1 | ||||
| -rw-r--r-- | core/java/android/app/BackStackEntry.java | 1 | ||||
| -rw-r--r-- | core/java/android/app/Fragment.java | 13 | ||||
| -rw-r--r-- | core/java/android/app/FragmentManager.java | 28 | ||||
| -rw-r--r-- | core/java/android/preference/PreferenceActivity.java | 4 | ||||
| -rw-r--r-- | core/java/android/preference/PreferenceFragment.java | 2 |
6 files changed, 44 insertions, 5 deletions
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index 3dcdc0a..97aa23e 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -4058,6 +4058,7 @@ public class Activity extends ContextThemeWrapper fragment.mFragmentId = id; fragment.mTag = tag; fragment.mImmediateActivity = this; + fragment.mFragmentManager = mFragments; // If this fragment is newly instantiated (either right now, or // from last saved state), then give it the attributes to // initialize itself. diff --git a/core/java/android/app/BackStackEntry.java b/core/java/android/app/BackStackEntry.java index 71fd5e5..296b495 100644 --- a/core/java/android/app/BackStackEntry.java +++ b/core/java/android/app/BackStackEntry.java @@ -205,6 +205,7 @@ final class BackStackEntry implements FragmentTransaction, Runnable { throw new IllegalStateException("Fragment already added: " + fragment); } fragment.mImmediateActivity = mManager.mActivity; + fragment.mFragmentManager = mManager; if (tag != null) { if (fragment.mTag != null && !tag.equals(fragment.mTag)) { diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java index 909e81f..1cbed79 100644 --- a/core/java/android/app/Fragment.java +++ b/core/java/android/app/Fragment.java @@ -94,6 +94,7 @@ final class FragmentState implements Parcelable { mInstance.mContainerId = mContainerId; mInstance.mTag = mTag; mInstance.mRetainInstance = mRetainInstance; + mInstance.mFragmentManager = activity.mFragments; return mInstance; } @@ -318,6 +319,11 @@ public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener // Number of active back stack entries this fragment is in. int mBackStackNesting; + // The fragment manager we are associated with. Set as soon as the + // fragment is used in a transaction; cleared after it has been removed + // from all transactions. + FragmentManager mFragmentManager; + // Set as soon as a fragment is added to a transaction (or removed), // to be able to do validation. Activity mImmediateActivity; @@ -578,10 +584,13 @@ public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener /** * Return the FragmentManager for interacting with fragments associated - * with this fragment's activity. + * with this fragment's activity. Note that this will be non-null slightly + * before {@link #getActivity()}, in the time from when the fragment is + * placed in a {@link FragmentTransaction} until it is committed and + * attached to its activity. */ final public FragmentManager getFragmentManager() { - return mActivity.mFragments; + return mFragmentManager; } /** diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java index 85a9d60..a704ec8 100644 --- a/core/java/android/app/FragmentManager.java +++ b/core/java/android/app/FragmentManager.java @@ -192,6 +192,7 @@ final class FragmentManagerImpl implements FragmentManager { Activity mActivity; boolean mNeedMenuInvalidate; + boolean mStateSaved; // Temporary vars for state save and restore. Bundle mStateBundle = null; @@ -484,6 +485,7 @@ final class FragmentManagerImpl implements FragmentManager { throw new SuperNotCalledException("Fragment " + f + " did not call through to super.onDetach()"); } + f.mImmediateActivity = null; f.mActivity = null; } } @@ -678,6 +680,10 @@ final class FragmentManagerImpl implements FragmentManager { } public void enqueueAction(Runnable action) { + if (mStateSaved) { + throw new IllegalStateException( + "Can not perform this action after onSaveInstanceState"); + } synchronized (this) { if (mPendingActions == null) { mPendingActions = new ArrayList<Runnable>(); @@ -888,6 +894,8 @@ final class FragmentManagerImpl implements FragmentManager { } Parcelable saveAllState() { + mStateSaved = true; + if (mActive == null || mActive.size() <= 0) { return null; } @@ -1029,6 +1037,22 @@ final class FragmentManagerImpl implements FragmentManager { } } + // Update the target of all retained fragments. + if (nonConfig != null) { + for (int i=0; i<nonConfig.size(); i++) { + Fragment f = nonConfig.get(i); + if (f.mTarget != null) { + if (f.mTarget.mIndex < mActive.size()) { + f.mTarget = mActive.get(f.mTarget.mIndex); + } else { + Log.w(TAG, "Re-attaching retained fragment " + f + + " target no longer exists: " + f.mTarget); + f.mTarget = null; + } + } + } + } + // Build the list of currently added fragments. if (fms.mAdded != null) { mAdded = new ArrayList<Fragment>(fms.mAdded.length); @@ -1070,18 +1094,22 @@ final class FragmentManagerImpl implements FragmentManager { } public void dispatchCreate() { + mStateSaved = false; moveToState(Fragment.CREATED, false); } public void dispatchActivityCreated() { + mStateSaved = false; moveToState(Fragment.ACTIVITY_CREATED, false); } public void dispatchStart() { + mStateSaved = false; moveToState(Fragment.STARTED, false); } public void dispatchResume() { + mStateSaved = false; moveToState(Fragment.RESUMED, false); } diff --git a/core/java/android/preference/PreferenceActivity.java b/core/java/android/preference/PreferenceActivity.java index c28ccd3..2efb09d 100644 --- a/core/java/android/preference/PreferenceActivity.java +++ b/core/java/android/preference/PreferenceActivity.java @@ -180,8 +180,8 @@ public abstract class PreferenceActivity extends ListActivity implements */ private static final int FIRST_REQUEST_CODE = 100; - private static final int MSG_BIND_PREFERENCES = 0; - private static final int MSG_BUILD_HEADERS = 1; + private static final int MSG_BIND_PREFERENCES = 1; + private static final int MSG_BUILD_HEADERS = 2; private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { diff --git a/core/java/android/preference/PreferenceFragment.java b/core/java/android/preference/PreferenceFragment.java index 0b5dffe..479497a 100644 --- a/core/java/android/preference/PreferenceFragment.java +++ b/core/java/android/preference/PreferenceFragment.java @@ -106,7 +106,7 @@ public abstract class PreferenceFragment extends Fragment implements */ private static final int FIRST_REQUEST_CODE = 100; - private static final int MSG_BIND_PREFERENCES = 0; + private static final int MSG_BIND_PREFERENCES = 1; private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { |
