OSDN Git Service

Fix a major problem in fragment lifecycle.
authorDianne Hackborn <hackbod@google.com>
Wed, 15 Jun 2011 01:36:14 +0000 (18:36 -0700)
committerDianne Hackborn <hackbod@google.com>
Wed, 15 Jun 2011 03:47:44 +0000 (20:47 -0700)
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

core/java/android/app/Fragment.java
core/java/android/app/FragmentManager.java
services/java/com/android/server/am/ActivityManagerService.java

index f2be9ad..26b3ceb 100644 (file)
@@ -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;
 
index f05e2b3..285f1c1 100644 (file)
@@ -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;
                     }
                 }
index 1a333ba..01bd7a9 100644 (file)
@@ -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;