Loading core/java/android/app/BackStackRecord.java +105 −53 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; import android.util.Log; import android.util.LogWriter; import java.io.FileDescriptor; import java.io.PrintWriter; Loading Loading @@ -94,11 +95,12 @@ final class BackStackState implements Parcelable { public BackStackRecord instantiate(FragmentManagerImpl fm) { BackStackRecord bse = new BackStackRecord(fm); int pos = 0; int num = 0; while (pos < mOps.length) { BackStackRecord.Op op = new BackStackRecord.Op(); op.cmd = mOps[pos++]; if (FragmentManagerImpl.DEBUG) Log.v(FragmentManagerImpl.TAG, "BSE " + bse + " set base fragment #" + mOps[pos]); "Instantiate " + bse + " op #" + num + " base fragment #" + mOps[pos]); int findex = mOps[pos++]; if (findex >= 0) { Fragment f = fm.mActive.get(findex); Loading @@ -115,12 +117,13 @@ final class BackStackState implements Parcelable { op.removed = new ArrayList<Fragment>(N); for (int i=0; i<N; i++) { if (FragmentManagerImpl.DEBUG) Log.v(FragmentManagerImpl.TAG, "BSE " + bse + " set remove fragment #" + mOps[pos]); "Instantiate " + bse + " set remove fragment #" + mOps[pos]); Fragment r = fm.mActive.get(mOps[pos++]); op.removed.add(r); } } bse.addOp(op); num++; } bse.mTransition = mTransition; bse.mTransitionStyle = mTransitionStyle; Loading Loading @@ -168,7 +171,7 @@ final class BackStackState implements Parcelable { */ final class BackStackRecord extends FragmentTransaction implements FragmentManager.BackStackEntry, Runnable { static final String TAG = "BackStackEntry"; static final String TAG = FragmentManagerImpl.TAG; final FragmentManagerImpl mManager; Loading Loading @@ -206,14 +209,36 @@ final class BackStackRecord extends FragmentTransaction implements boolean mAllowAddToBackStack = true; String mName; boolean mCommitted; int mIndex; int mIndex = -1; int mBreadCrumbTitleRes; CharSequence mBreadCrumbTitleText; int mBreadCrumbShortTitleRes; CharSequence mBreadCrumbShortTitleText; @Override public String toString() { StringBuilder sb = new StringBuilder(128); sb.append("BackStackEntry{"); sb.append(Integer.toHexString(System.identityHashCode(this))); if (mIndex >= 0) { sb.append(" #"); sb.append(mIndex); } if (mName != null) { sb.append(" "); sb.append(mName); } sb.append("}"); return sb.toString(); } public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) { dump(prefix, writer, true); } void dump(String prefix, PrintWriter writer, boolean full) { if (full) { writer.print(prefix); writer.print("mName="); writer.print(mName); writer.print(" mIndex="); writer.print(mIndex); writer.print(" mCommitted="); writer.println(mCommitted); Loading Loading @@ -247,6 +272,7 @@ final class BackStackRecord extends FragmentTransaction implements writer.print(" mBreadCrumbShortTitleText="); writer.println(mBreadCrumbShortTitleText); } } if (mHead != null) { writer.print(prefix); writer.println("Operations:"); Loading @@ -254,36 +280,52 @@ final class BackStackRecord extends FragmentTransaction implements Op op = mHead; int num = 0; while (op != null) { String cmdStr; switch (op.cmd) { case OP_NULL: cmdStr="NULL"; break; case OP_ADD: cmdStr="ADD"; break; case OP_REPLACE: cmdStr="REPLACE"; break; case OP_REMOVE: cmdStr="REMOVE"; break; case OP_HIDE: cmdStr="HIDE"; break; case OP_SHOW: cmdStr="SHOW"; break; case OP_DETACH: cmdStr="DETACH"; break; case OP_ATTACH: cmdStr="ATTACH"; break; default: cmdStr="cmd=" + op.cmd; break; } writer.print(prefix); writer.print(" Op #"); writer.print(num); writer.println(":"); writer.print(innerPrefix); writer.print("cmd="); writer.print(op.cmd); writer.print(" fragment="); writer.println(op.fragment); writer.print(": "); writer.print(cmdStr); writer.print(" "); writer.println(op.fragment); if (full) { if (op.enterAnim != 0 || op.exitAnim != 0) { writer.print(prefix); writer.print("enterAnim=#"); writer.print(innerPrefix); writer.print("enterAnim=#"); writer.print(Integer.toHexString(op.enterAnim)); writer.print(" exitAnim=#"); writer.println(Integer.toHexString(op.exitAnim)); } if (op.popEnterAnim != 0 || op.popExitAnim != 0) { writer.print(prefix); writer.print("popEnterAnim=#"); writer.print(innerPrefix); writer.print("popEnterAnim=#"); writer.print(Integer.toHexString(op.popEnterAnim)); writer.print(" popExitAnim=#"); writer.println(Integer.toHexString(op.popExitAnim)); } } if (op.removed != null && op.removed.size() > 0) { for (int i=0; i<op.removed.size(); i++) { writer.print(innerPrefix); if (op.removed.size() == 1) { writer.print("Removed: "); } else { if (i == 0) { writer.println("Removed:"); writer.print(innerPrefix); writer.print(" #"); writer.print(num); } writer.print(innerPrefix); writer.print(" #"); writer.print(i); writer.print(": "); } writer.println(op.removed.get(i)); } } op = op.next; num++; } } } Loading Loading @@ -538,7 +580,12 @@ final class BackStackRecord extends FragmentTransaction implements int commitInternal(boolean allowStateLoss) { if (mCommitted) throw new IllegalStateException("commit already called"); if (FragmentManagerImpl.DEBUG) Log.v(TAG, "Commit: " + this); if (FragmentManagerImpl.DEBUG) { Log.v(TAG, "Commit: " + this); LogWriter logw = new LogWriter(Log.VERBOSE, TAG); PrintWriter pw = new PrintWriter(logw); dump(" ", null, pw, null); } mCommitted = true; if (mAddToBackStack) { mIndex = mManager.allocBackStackIndex(this); Loading Loading @@ -641,7 +688,12 @@ final class BackStackRecord extends FragmentTransaction implements } public void popFromBackStack(boolean doStateMove) { if (FragmentManagerImpl.DEBUG) Log.v(TAG, "popFromBackStack: " + this); if (FragmentManagerImpl.DEBUG) { Log.v(TAG, "popFromBackStack: " + this); LogWriter logw = new LogWriter(Log.VERBOSE, TAG); PrintWriter pw = new PrintWriter(logw); dump(" ", null, pw, null); } bumpBackStackNesting(-1); Loading core/java/android/app/FragmentManager.java +32 −8 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import android.animation.AnimatorListenerAdapter; import android.content.res.Configuration; import android.content.res.TypedArray; import android.os.Bundle; import android.os.Debug; import android.os.Handler; import android.os.Looper; import android.os.Parcel; Loading Loading @@ -771,9 +772,9 @@ final class FragmentManagerImpl extends FragmentManager { void moveToState(Fragment f, int newState, int transit, int transitionStyle, boolean keepActive) { //if (DEBUG) Log.v(TAG, "moveToState: " + f // + " oldState=" + f.mState + " newState=" + newState // + " mRemoving=" + f.mRemoving + " Callers=" + Debug.getCallers(5)); if (DEBUG && false) Log.v(TAG, "moveToState: " + f + " oldState=" + f.mState + " newState=" + newState + " mRemoving=" + f.mRemoving + " Callers=" + Debug.getCallers(5)); // Fragments that are not currently added will sit in the onCreate() state. if ((!f.mAdded || f.mDetached) && newState > Fragment.CREATED) { Loading Loading @@ -1112,6 +1113,9 @@ final class FragmentManagerImpl extends FragmentManager { if (DEBUG) Log.v(TAG, "add: " + fragment); makeActive(fragment); if (!fragment.mDetached) { if (mAdded.contains(fragment)) { throw new IllegalStateException("Fragment already added: " + fragment); } mAdded.add(fragment); fragment.mAdded = true; fragment.mRemoving = false; Loading @@ -1128,6 +1132,14 @@ final class FragmentManagerImpl extends FragmentManager { if (DEBUG) Log.v(TAG, "remove: " + fragment + " nesting=" + fragment.mBackStackNesting); final boolean inactive = !fragment.isInBackStack(); if (!fragment.mDetached || inactive) { if (false) { // Would be nice to catch a bad remove here, but we need // time to test this to make sure we aren't crashes cases // where it is not a problem. if (!mAdded.contains(fragment)) { throw new IllegalStateException("Fragment not added: " + fragment); } } if (mAdded != null) { mAdded.remove(fragment); } Loading Loading @@ -1200,6 +1212,7 @@ final class FragmentManagerImpl extends FragmentManager { if (fragment.mAdded) { // We are not already in back stack, so need to remove the fragment. if (mAdded != null) { if (DEBUG) Log.v(TAG, "remove from detach: " + fragment); mAdded.remove(fragment); } if (fragment.mHasMenu && fragment.mMenuVisible) { Loading @@ -1219,6 +1232,10 @@ final class FragmentManagerImpl extends FragmentManager { if (mAdded == null) { mAdded = new ArrayList<Fragment>(); } if (mAdded.contains(fragment)) { throw new IllegalStateException("Fragment already added: " + fragment); } if (DEBUG) Log.v(TAG, "add from attach: " + fragment); mAdded.add(fragment); fragment.mAdded = true; if (fragment.mHasMenu && fragment.mMenuVisible) { Loading Loading @@ -1717,19 +1734,18 @@ final class FragmentManagerImpl extends FragmentManager { FragmentState fs = fms.mActive[i]; if (fs != null) { Fragment f = fs.instantiate(mActivity, mParent); if (DEBUG) Log.v(TAG, "restoreAllState: adding #" + i + ": " + f); if (DEBUG) Log.v(TAG, "restoreAllState: active #" + i + ": " + f); mActive.add(f); // Now that the fragment is instantiated (or came from being // retained above), clear mInstance in case we end up re-restoring // from this FragmentState again. fs.mInstance = null; } else { if (DEBUG) Log.v(TAG, "restoreAllState: adding #" + i + ": (null)"); mActive.add(null); if (mAvailIndices == null) { mAvailIndices = new ArrayList<Integer>(); } if (DEBUG) Log.v(TAG, "restoreAllState: adding avail #" + i); if (DEBUG) Log.v(TAG, "restoreAllState: avail #" + i); mAvailIndices.add(i); } } Loading Loading @@ -1760,7 +1776,10 @@ final class FragmentManagerImpl extends FragmentManager { "No instantiated fragment for index #" + fms.mAdded[i])); } f.mAdded = true; if (DEBUG) Log.v(TAG, "restoreAllState: making added #" + i + ": " + f); if (DEBUG) Log.v(TAG, "restoreAllState: added #" + i + ": " + f); if (mAdded.contains(f)) { throw new IllegalStateException("Already added!"); } mAdded.add(f); } } else { Loading @@ -1772,8 +1791,13 @@ final class FragmentManagerImpl extends FragmentManager { mBackStack = new ArrayList<BackStackRecord>(fms.mBackStack.length); for (int i=0; i<fms.mBackStack.length; i++) { BackStackRecord bse = fms.mBackStack[i].instantiate(this); if (DEBUG) Log.v(TAG, "restoreAllState: adding bse #" + i if (DEBUG) { Log.v(TAG, "restoreAllState: back stack #" + i + " (index " + bse.mIndex + "): " + bse); LogWriter logw = new LogWriter(Log.VERBOSE, TAG); PrintWriter pw = new PrintWriter(logw); bse.dump(" ", pw, false); } mBackStack.add(bse); if (bse.mIndex >= 0) { setBackStackIndex(bse.mIndex, bse); Loading Loading
core/java/android/app/BackStackRecord.java +105 −53 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; import android.util.Log; import android.util.LogWriter; import java.io.FileDescriptor; import java.io.PrintWriter; Loading Loading @@ -94,11 +95,12 @@ final class BackStackState implements Parcelable { public BackStackRecord instantiate(FragmentManagerImpl fm) { BackStackRecord bse = new BackStackRecord(fm); int pos = 0; int num = 0; while (pos < mOps.length) { BackStackRecord.Op op = new BackStackRecord.Op(); op.cmd = mOps[pos++]; if (FragmentManagerImpl.DEBUG) Log.v(FragmentManagerImpl.TAG, "BSE " + bse + " set base fragment #" + mOps[pos]); "Instantiate " + bse + " op #" + num + " base fragment #" + mOps[pos]); int findex = mOps[pos++]; if (findex >= 0) { Fragment f = fm.mActive.get(findex); Loading @@ -115,12 +117,13 @@ final class BackStackState implements Parcelable { op.removed = new ArrayList<Fragment>(N); for (int i=0; i<N; i++) { if (FragmentManagerImpl.DEBUG) Log.v(FragmentManagerImpl.TAG, "BSE " + bse + " set remove fragment #" + mOps[pos]); "Instantiate " + bse + " set remove fragment #" + mOps[pos]); Fragment r = fm.mActive.get(mOps[pos++]); op.removed.add(r); } } bse.addOp(op); num++; } bse.mTransition = mTransition; bse.mTransitionStyle = mTransitionStyle; Loading Loading @@ -168,7 +171,7 @@ final class BackStackState implements Parcelable { */ final class BackStackRecord extends FragmentTransaction implements FragmentManager.BackStackEntry, Runnable { static final String TAG = "BackStackEntry"; static final String TAG = FragmentManagerImpl.TAG; final FragmentManagerImpl mManager; Loading Loading @@ -206,14 +209,36 @@ final class BackStackRecord extends FragmentTransaction implements boolean mAllowAddToBackStack = true; String mName; boolean mCommitted; int mIndex; int mIndex = -1; int mBreadCrumbTitleRes; CharSequence mBreadCrumbTitleText; int mBreadCrumbShortTitleRes; CharSequence mBreadCrumbShortTitleText; @Override public String toString() { StringBuilder sb = new StringBuilder(128); sb.append("BackStackEntry{"); sb.append(Integer.toHexString(System.identityHashCode(this))); if (mIndex >= 0) { sb.append(" #"); sb.append(mIndex); } if (mName != null) { sb.append(" "); sb.append(mName); } sb.append("}"); return sb.toString(); } public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) { dump(prefix, writer, true); } void dump(String prefix, PrintWriter writer, boolean full) { if (full) { writer.print(prefix); writer.print("mName="); writer.print(mName); writer.print(" mIndex="); writer.print(mIndex); writer.print(" mCommitted="); writer.println(mCommitted); Loading Loading @@ -247,6 +272,7 @@ final class BackStackRecord extends FragmentTransaction implements writer.print(" mBreadCrumbShortTitleText="); writer.println(mBreadCrumbShortTitleText); } } if (mHead != null) { writer.print(prefix); writer.println("Operations:"); Loading @@ -254,36 +280,52 @@ final class BackStackRecord extends FragmentTransaction implements Op op = mHead; int num = 0; while (op != null) { String cmdStr; switch (op.cmd) { case OP_NULL: cmdStr="NULL"; break; case OP_ADD: cmdStr="ADD"; break; case OP_REPLACE: cmdStr="REPLACE"; break; case OP_REMOVE: cmdStr="REMOVE"; break; case OP_HIDE: cmdStr="HIDE"; break; case OP_SHOW: cmdStr="SHOW"; break; case OP_DETACH: cmdStr="DETACH"; break; case OP_ATTACH: cmdStr="ATTACH"; break; default: cmdStr="cmd=" + op.cmd; break; } writer.print(prefix); writer.print(" Op #"); writer.print(num); writer.println(":"); writer.print(innerPrefix); writer.print("cmd="); writer.print(op.cmd); writer.print(" fragment="); writer.println(op.fragment); writer.print(": "); writer.print(cmdStr); writer.print(" "); writer.println(op.fragment); if (full) { if (op.enterAnim != 0 || op.exitAnim != 0) { writer.print(prefix); writer.print("enterAnim=#"); writer.print(innerPrefix); writer.print("enterAnim=#"); writer.print(Integer.toHexString(op.enterAnim)); writer.print(" exitAnim=#"); writer.println(Integer.toHexString(op.exitAnim)); } if (op.popEnterAnim != 0 || op.popExitAnim != 0) { writer.print(prefix); writer.print("popEnterAnim=#"); writer.print(innerPrefix); writer.print("popEnterAnim=#"); writer.print(Integer.toHexString(op.popEnterAnim)); writer.print(" popExitAnim=#"); writer.println(Integer.toHexString(op.popExitAnim)); } } if (op.removed != null && op.removed.size() > 0) { for (int i=0; i<op.removed.size(); i++) { writer.print(innerPrefix); if (op.removed.size() == 1) { writer.print("Removed: "); } else { if (i == 0) { writer.println("Removed:"); writer.print(innerPrefix); writer.print(" #"); writer.print(num); } writer.print(innerPrefix); writer.print(" #"); writer.print(i); writer.print(": "); } writer.println(op.removed.get(i)); } } op = op.next; num++; } } } Loading Loading @@ -538,7 +580,12 @@ final class BackStackRecord extends FragmentTransaction implements int commitInternal(boolean allowStateLoss) { if (mCommitted) throw new IllegalStateException("commit already called"); if (FragmentManagerImpl.DEBUG) Log.v(TAG, "Commit: " + this); if (FragmentManagerImpl.DEBUG) { Log.v(TAG, "Commit: " + this); LogWriter logw = new LogWriter(Log.VERBOSE, TAG); PrintWriter pw = new PrintWriter(logw); dump(" ", null, pw, null); } mCommitted = true; if (mAddToBackStack) { mIndex = mManager.allocBackStackIndex(this); Loading Loading @@ -641,7 +688,12 @@ final class BackStackRecord extends FragmentTransaction implements } public void popFromBackStack(boolean doStateMove) { if (FragmentManagerImpl.DEBUG) Log.v(TAG, "popFromBackStack: " + this); if (FragmentManagerImpl.DEBUG) { Log.v(TAG, "popFromBackStack: " + this); LogWriter logw = new LogWriter(Log.VERBOSE, TAG); PrintWriter pw = new PrintWriter(logw); dump(" ", null, pw, null); } bumpBackStackNesting(-1); Loading
core/java/android/app/FragmentManager.java +32 −8 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import android.animation.AnimatorListenerAdapter; import android.content.res.Configuration; import android.content.res.TypedArray; import android.os.Bundle; import android.os.Debug; import android.os.Handler; import android.os.Looper; import android.os.Parcel; Loading Loading @@ -771,9 +772,9 @@ final class FragmentManagerImpl extends FragmentManager { void moveToState(Fragment f, int newState, int transit, int transitionStyle, boolean keepActive) { //if (DEBUG) Log.v(TAG, "moveToState: " + f // + " oldState=" + f.mState + " newState=" + newState // + " mRemoving=" + f.mRemoving + " Callers=" + Debug.getCallers(5)); if (DEBUG && false) Log.v(TAG, "moveToState: " + f + " oldState=" + f.mState + " newState=" + newState + " mRemoving=" + f.mRemoving + " Callers=" + Debug.getCallers(5)); // Fragments that are not currently added will sit in the onCreate() state. if ((!f.mAdded || f.mDetached) && newState > Fragment.CREATED) { Loading Loading @@ -1112,6 +1113,9 @@ final class FragmentManagerImpl extends FragmentManager { if (DEBUG) Log.v(TAG, "add: " + fragment); makeActive(fragment); if (!fragment.mDetached) { if (mAdded.contains(fragment)) { throw new IllegalStateException("Fragment already added: " + fragment); } mAdded.add(fragment); fragment.mAdded = true; fragment.mRemoving = false; Loading @@ -1128,6 +1132,14 @@ final class FragmentManagerImpl extends FragmentManager { if (DEBUG) Log.v(TAG, "remove: " + fragment + " nesting=" + fragment.mBackStackNesting); final boolean inactive = !fragment.isInBackStack(); if (!fragment.mDetached || inactive) { if (false) { // Would be nice to catch a bad remove here, but we need // time to test this to make sure we aren't crashes cases // where it is not a problem. if (!mAdded.contains(fragment)) { throw new IllegalStateException("Fragment not added: " + fragment); } } if (mAdded != null) { mAdded.remove(fragment); } Loading Loading @@ -1200,6 +1212,7 @@ final class FragmentManagerImpl extends FragmentManager { if (fragment.mAdded) { // We are not already in back stack, so need to remove the fragment. if (mAdded != null) { if (DEBUG) Log.v(TAG, "remove from detach: " + fragment); mAdded.remove(fragment); } if (fragment.mHasMenu && fragment.mMenuVisible) { Loading @@ -1219,6 +1232,10 @@ final class FragmentManagerImpl extends FragmentManager { if (mAdded == null) { mAdded = new ArrayList<Fragment>(); } if (mAdded.contains(fragment)) { throw new IllegalStateException("Fragment already added: " + fragment); } if (DEBUG) Log.v(TAG, "add from attach: " + fragment); mAdded.add(fragment); fragment.mAdded = true; if (fragment.mHasMenu && fragment.mMenuVisible) { Loading Loading @@ -1717,19 +1734,18 @@ final class FragmentManagerImpl extends FragmentManager { FragmentState fs = fms.mActive[i]; if (fs != null) { Fragment f = fs.instantiate(mActivity, mParent); if (DEBUG) Log.v(TAG, "restoreAllState: adding #" + i + ": " + f); if (DEBUG) Log.v(TAG, "restoreAllState: active #" + i + ": " + f); mActive.add(f); // Now that the fragment is instantiated (or came from being // retained above), clear mInstance in case we end up re-restoring // from this FragmentState again. fs.mInstance = null; } else { if (DEBUG) Log.v(TAG, "restoreAllState: adding #" + i + ": (null)"); mActive.add(null); if (mAvailIndices == null) { mAvailIndices = new ArrayList<Integer>(); } if (DEBUG) Log.v(TAG, "restoreAllState: adding avail #" + i); if (DEBUG) Log.v(TAG, "restoreAllState: avail #" + i); mAvailIndices.add(i); } } Loading Loading @@ -1760,7 +1776,10 @@ final class FragmentManagerImpl extends FragmentManager { "No instantiated fragment for index #" + fms.mAdded[i])); } f.mAdded = true; if (DEBUG) Log.v(TAG, "restoreAllState: making added #" + i + ": " + f); if (DEBUG) Log.v(TAG, "restoreAllState: added #" + i + ": " + f); if (mAdded.contains(f)) { throw new IllegalStateException("Already added!"); } mAdded.add(f); } } else { Loading @@ -1772,8 +1791,13 @@ final class FragmentManagerImpl extends FragmentManager { mBackStack = new ArrayList<BackStackRecord>(fms.mBackStack.length); for (int i=0; i<fms.mBackStack.length; i++) { BackStackRecord bse = fms.mBackStack[i].instantiate(this); if (DEBUG) Log.v(TAG, "restoreAllState: adding bse #" + i if (DEBUG) { Log.v(TAG, "restoreAllState: back stack #" + i + " (index " + bse.mIndex + "): " + bse); LogWriter logw = new LogWriter(Log.VERBOSE, TAG); PrintWriter pw = new PrintWriter(logw); bse.dump(" ", pw, false); } mBackStack.add(bse); if (bse.mIndex >= 0) { setBackStackIndex(bse.mIndex, bse); Loading