diff options
author | Dianne Hackborn <hackbod@google.com> | 2011-06-14 18:36:14 -0700 |
---|---|---|
committer | Dianne Hackborn <hackbod@google.com> | 2011-06-14 20:47:44 -0700 |
commit | f930232fd1c8d301d91853c8fe5dca43979ac807 (patch) | |
tree | 6609c0215f9888761749d4f96d088e604c9bca18 | |
parent | 4e04380d0a42347013808ee2058c786582ad548f (diff) | |
download | frameworks_base-f930232fd1c8d301d91853c8fe5dca43979ac807.zip frameworks_base-f930232fd1c8d301d91853c8fe5dca43979ac807.tar.gz frameworks_base-f930232fd1c8d301d91853c8fe5dca43979ac807.tar.bz2 |
Fix a major problem in fragment lifecycle.
When animating away a fragment, we were not putting it through
the last part of its lifecycle (onDestroy() etc).
Also, retained fragments that have a target were broken. Oops.
Change-Id: I5a669b77a2f24b581cde2a0959acf62edb65e326
-rw-r--r-- | core/java/android/app/Fragment.java | 3 | ||||
-rw-r--r-- | core/java/android/app/FragmentManager.java | 28 | ||||
-rw-r--r-- | services/java/com/android/server/am/ActivityManagerService.java | 10 |
3 files changed, 30 insertions, 11 deletions
diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java index f2be9ad..26b3ceb 100644 --- a/core/java/android/app/Fragment.java +++ b/core/java/android/app/Fragment.java @@ -367,6 +367,9 @@ public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener // Target fragment. Fragment mTarget; + // For use when retaining a fragment: this is the index of the last mTarget. + int mTargetIndex = -1; + // Target request code. int mTargetRequestCode; diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java index f05e2b3..285f1c1 100644 --- a/core/java/android/app/FragmentManager.java +++ b/core/java/android/app/FragmentManager.java @@ -695,6 +695,10 @@ final class FragmentManagerImpl extends FragmentManager { if (!f.mAdded && newState > Fragment.CREATED) { newState = Fragment.CREATED; } + if (f.mRemoving && newState > f.mState) { + // While removing a fragment, we can't change it to a higher state. + newState = f.mState; + } if (f.mState < newState) { // For fragments that are created from a layout, when restoring from @@ -915,6 +919,7 @@ final class FragmentManagerImpl extends FragmentManager { // the fragment now should move to once the animation // is done. f.mStateAfterAnimating = newState; + newState = Fragment.CREATED; } else { if (DEBUG) Log.v(TAG, "movefrom CREATED: " + f); if (!f.mRetaining) { @@ -932,9 +937,13 @@ final class FragmentManagerImpl extends FragmentManager { throw new SuperNotCalledException("Fragment " + f + " did not call through to super.onDetach()"); } - f.mImmediateActivity = null; - f.mActivity = null; - f.mFragmentManager = null; + if (!f.mRetaining) { + makeInactive(f); + } else { + f.mImmediateActivity = null; + f.mActivity = null; + f.mFragmentManager = null; + } } } } @@ -1040,9 +1049,6 @@ final class FragmentManagerImpl extends FragmentManager { fragment.mRemoving = true; moveToState(fragment, inactive ? Fragment.INITIALIZING : Fragment.CREATED, transition, transitionStyle); - if (inactive) { - makeInactive(fragment); - } } } @@ -1397,6 +1403,7 @@ final class FragmentManagerImpl extends FragmentManager { } fragments.add(f); f.mRetaining = true; + f.mTargetIndex = f.mTarget != null ? f.mTarget.mIndex : -1; } } } @@ -1561,6 +1568,7 @@ final class FragmentManagerImpl extends FragmentManager { f.mBackStackNesting = 0; f.mInLayout = false; f.mAdded = false; + f.mTarget = null; if (fs.mSavedFragmentState != null) { fs.mSavedFragmentState.setClassLoader(mActivity.getClassLoader()); f.mSavedViewState = fs.mSavedFragmentState.getSparseParcelableArray( @@ -1600,12 +1608,12 @@ final class FragmentManagerImpl extends FragmentManager { 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); + if (f.mTargetIndex >= 0) { + if (f.mTargetIndex < mActive.size()) { + f.mTarget = mActive.get(f.mTargetIndex); } else { Log.w(TAG, "Re-attaching retained fragment " + f - + " target no longer exists: " + f.mTarget); + + " target no longer exists: " + f.mTargetIndex); f.mTarget = null; } } diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index 1a333ba..01bd7a9 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -7536,7 +7536,8 @@ public final class ActivityManagerService extends ActivityManagerNative pw.println(" COMP_SPEC may also be a component name (com.foo/.myApp),"); pw.println(" a partial substring in a component name, an"); pw.println(" ActivityRecord hex object identifier, or"); - pw.println(" \"all\" for all objects"); + pw.println(" \"all\" for all objects, or"); + pw.println(" \"top\" for the top activity."); pw.println(" -a: include all available server state."); pw.println(" -c: include client state."); return; @@ -8090,6 +8091,13 @@ public final class ActivityManagerService extends ActivityManagerNative activities.add(r1); } } + } else if ("top".equals(name)) { + synchronized (this) { + final int N = mMainStack.mHistory.size(); + if (N > 0) { + activities.add((ActivityRecord)mMainStack.mHistory.get(N-1)); + } + } } else { ComponentName componentName = ComponentName.unflattenFromString(name); int objectId = 0; |