java.lang.IllegalStateException
Can not perform this action after onSaveInstanceState
1 android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:4) |
---|
2 android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1) |
3 android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:12) |
4 android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:1) |
5 android.support.v4.app.DialogFragment.show(DialogFragment.java:5) |
一般出現場景都是開啓一個異步任務 結束之後使用DialogFragment進行展示內容 ,接下來給大家分析下爲何會發生這樣異常,如何避免
public void show(FragmentManager manager, String tag) {
this.mDismissed = false;
this.mShownByMe = true;
FragmentTransaction ft = manager.beginTransaction();
ft.add(this, tag);
ft.commit();
}
public int commit() {
return this.commitInternal(false);
}
在看commistInternal方法
int commitInternal(boolean allowStateLoss) {
if (this.mCommitted) {
throw new IllegalStateException("commit already called");
} else {
if (FragmentManagerImpl.DEBUG) {
Log.v("FragmentManager", "Commit: " + this);
LogWriter logw = new LogWriter("FragmentManager");
PrintWriter pw = new PrintWriter(logw);
this.dump(" ", (FileDescriptor)null, pw, (String[])null);
pw.close();
}
this.mCommitted = true;
if (this.mAddToBackStack) {
this.mIndex = this.mManager.allocBackStackIndex(this);
} else {
this.mIndex = -1;
}
this.mManager.enqueueAction(this, allowStateLoss);
return this.mIndex;
}
}
這裏參數傳的是false 標示顯示的fragment不允許狀態丟失,接下來看enqueueAction方法
public void enqueueAction(FragmentManagerImpl.OpGenerator action, boolean allowStateLoss) {
if (!allowStateLoss) {
this.checkStateLoss();
}
synchronized(this) {
if (!this.mDestroyed && this.mHost != null) {
if (this.mPendingActions == null) {
this.mPendingActions = new ArrayList();
}
this.mPendingActions.add(action);
this.scheduleCommit();
} else if (!allowStateLoss) {
throw new IllegalStateException("Activity has been destroyed");
}
}
}
我們可以看到如果不允許狀態丟失會check一下 在看checkStateLoss方法
private void checkStateLoss() {
if (this.isStateSaved()) {
throw new IllegalStateException("Can not perform this action after onSaveInstanceState");
} else if (this.mNoTransactionsBecause != null) {
throw new IllegalStateException("Can not perform this action inside of " + this.mNoTransactionsBecause);
}
}
首先判斷了狀態是否已經報錯 true則拋出異常,在看如何進行判斷的isStateSaved方法
public boolean isStateSaved() {
return this.mStateSaved || this.mStopped;
}
有兩個表示值mStateSaved 和mStopped 只要有任何一個狀態滿足則返回true
由此可以總結出當activity調用了 onSaveInstanceState方法後或者activity處於stopped狀態時候 使用FragmentManager的FragmentTransaction.commit方法提交拋出這樣"Can not perform this action after onSaveInstanceState"異常 直接導致程序crash
解決方案也就很簡單了 只要保證activity的狀態 不是isStateSaved狀態使用FragmentManager的FragmentTransaction.commit 提交fragment就可以了
ps多看看源碼有助於我們更好的使用系統提供的api
文章有什麼不對的地方大家斧正