Merge "Work on issue #7232641: ISE crash when rotating phone in label list mode" into jb-mr1-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
66442c7e7b
@@ -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;
|
||||
@@ -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);
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
|
||||
@@ -206,46 +209,69 @@ 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) {
|
||||
writer.print(prefix); writer.print("mName="); writer.print(mName);
|
||||
writer.print(" mIndex="); writer.print(mIndex);
|
||||
writer.print(" mCommitted="); writer.println(mCommitted);
|
||||
if (mTransition != FragmentTransaction.TRANSIT_NONE) {
|
||||
writer.print(prefix); writer.print("mTransition=#");
|
||||
writer.print(Integer.toHexString(mTransition));
|
||||
writer.print(" mTransitionStyle=#");
|
||||
writer.println(Integer.toHexString(mTransitionStyle));
|
||||
}
|
||||
if (mEnterAnim != 0 || mExitAnim !=0) {
|
||||
writer.print(prefix); writer.print("mEnterAnim=#");
|
||||
writer.print(Integer.toHexString(mEnterAnim));
|
||||
writer.print(" mExitAnim=#");
|
||||
writer.println(Integer.toHexString(mExitAnim));
|
||||
}
|
||||
if (mPopEnterAnim != 0 || mPopExitAnim !=0) {
|
||||
writer.print(prefix); writer.print("mPopEnterAnim=#");
|
||||
writer.print(Integer.toHexString(mPopEnterAnim));
|
||||
writer.print(" mPopExitAnim=#");
|
||||
writer.println(Integer.toHexString(mPopExitAnim));
|
||||
}
|
||||
if (mBreadCrumbTitleRes != 0 || mBreadCrumbTitleText != null) {
|
||||
writer.print(prefix); writer.print("mBreadCrumbTitleRes=#");
|
||||
writer.print(Integer.toHexString(mBreadCrumbTitleRes));
|
||||
writer.print(" mBreadCrumbTitleText=");
|
||||
writer.println(mBreadCrumbTitleText);
|
||||
}
|
||||
if (mBreadCrumbShortTitleRes != 0 || mBreadCrumbShortTitleText != null) {
|
||||
writer.print(prefix); writer.print("mBreadCrumbShortTitleRes=#");
|
||||
writer.print(Integer.toHexString(mBreadCrumbShortTitleRes));
|
||||
writer.print(" mBreadCrumbShortTitleText=");
|
||||
writer.println(mBreadCrumbShortTitleText);
|
||||
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);
|
||||
if (mTransition != FragmentTransaction.TRANSIT_NONE) {
|
||||
writer.print(prefix); writer.print("mTransition=#");
|
||||
writer.print(Integer.toHexString(mTransition));
|
||||
writer.print(" mTransitionStyle=#");
|
||||
writer.println(Integer.toHexString(mTransitionStyle));
|
||||
}
|
||||
if (mEnterAnim != 0 || mExitAnim !=0) {
|
||||
writer.print(prefix); writer.print("mEnterAnim=#");
|
||||
writer.print(Integer.toHexString(mEnterAnim));
|
||||
writer.print(" mExitAnim=#");
|
||||
writer.println(Integer.toHexString(mExitAnim));
|
||||
}
|
||||
if (mPopEnterAnim != 0 || mPopExitAnim !=0) {
|
||||
writer.print(prefix); writer.print("mPopEnterAnim=#");
|
||||
writer.print(Integer.toHexString(mPopEnterAnim));
|
||||
writer.print(" mPopExitAnim=#");
|
||||
writer.println(Integer.toHexString(mPopExitAnim));
|
||||
}
|
||||
if (mBreadCrumbTitleRes != 0 || mBreadCrumbTitleText != null) {
|
||||
writer.print(prefix); writer.print("mBreadCrumbTitleRes=#");
|
||||
writer.print(Integer.toHexString(mBreadCrumbTitleRes));
|
||||
writer.print(" mBreadCrumbTitleText=");
|
||||
writer.println(mBreadCrumbTitleText);
|
||||
}
|
||||
if (mBreadCrumbShortTitleRes != 0 || mBreadCrumbShortTitleText != null) {
|
||||
writer.print(prefix); writer.print("mBreadCrumbShortTitleRes=#");
|
||||
writer.print(Integer.toHexString(mBreadCrumbShortTitleRes));
|
||||
writer.print(" mBreadCrumbShortTitleText=");
|
||||
writer.println(mBreadCrumbShortTitleText);
|
||||
}
|
||||
}
|
||||
|
||||
if (mHead != null) {
|
||||
@@ -254,21 +280,34 @@ final class BackStackRecord extends FragmentTransaction implements
|
||||
Op op = mHead;
|
||||
int num = 0;
|
||||
while (op != null) {
|
||||
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);
|
||||
if (op.enterAnim != 0 || op.exitAnim != 0) {
|
||||
writer.print(prefix); writer.print("enterAnim=#");
|
||||
writer.print(Integer.toHexString(op.enterAnim));
|
||||
writer.print(" exitAnim=#");
|
||||
writer.println(Integer.toHexString(op.exitAnim));
|
||||
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;
|
||||
}
|
||||
if (op.popEnterAnim != 0 || op.popExitAnim != 0) {
|
||||
writer.print(prefix); writer.print("popEnterAnim=#");
|
||||
writer.print(Integer.toHexString(op.popEnterAnim));
|
||||
writer.print(" popExitAnim=#");
|
||||
writer.println(Integer.toHexString(op.popExitAnim));
|
||||
writer.print(prefix); writer.print(" Op #"); writer.print(num);
|
||||
writer.print(": "); writer.print(cmdStr);
|
||||
writer.print(" "); writer.println(op.fragment);
|
||||
if (full) {
|
||||
if (op.enterAnim != 0 || op.exitAnim != 0) {
|
||||
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(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++) {
|
||||
@@ -276,14 +315,17 @@ final class BackStackRecord extends FragmentTransaction implements
|
||||
if (op.removed.size() == 1) {
|
||||
writer.print("Removed: ");
|
||||
} else {
|
||||
writer.println("Removed:");
|
||||
writer.print(innerPrefix); writer.print(" #"); writer.print(num);
|
||||
if (i == 0) {
|
||||
writer.println("Removed:");
|
||||
}
|
||||
writer.print(innerPrefix); writer.print(" #"); writer.print(i);
|
||||
writer.print(": ");
|
||||
}
|
||||
writer.println(op.removed.get(i));
|
||||
}
|
||||
}
|
||||
op = op.next;
|
||||
num++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
@@ -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) {
|
||||
@@ -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;
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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) {
|
||||
@@ -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) {
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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 {
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user