1. 程式人生 > >fragment/dialogfragment異常:Can not perform this action after onSaveInstanceState

fragment/dialogfragment異常:Can not perform this action after onSaveInstanceState

專案在測試的時候未出現崩潰,但是上線之後奔潰日誌中發現有相當數量的報錯資訊如下:

java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1538)
at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1556)
at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:696)
at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:662)
at android.support.v4.app.DialogFragment.show(DialogFragment.java:143)
at com.hsl.stock.view.activity.NewWebActivity15.

run(NewWebActivity.java:699)atandroid.os.Handler.handleCallback(Handler.java:743)atandroid.os.Handler.dispatchMessage(Handler.java:95)atandroid.os.Looper.loop(Looper.java:150)atandroid.app.ActivityThread.main(ActivityThread.java:5665)atjava.lang.reflect.Method.invoke(NativeMethod)atcom.android.intern
al.os.ZygoteInit
MethodAndArgsCaller.run(ZygoteInit.java:799)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:689)

根據異常資訊Can not perform this action after onSaveInstanceState,可以瞭解到異常原因:在onSaveInstanceState行為之後,app執行某個不能響應的行為而導致異常發生。
檢視對應的錯誤資訊發現時fragment的commit()方法造成的崩潰.檢視官網解決辦法是將commit()方法換乘commitAllowingStateLoss ()方法.具體檢視

關於commitAllowingStateLoss ()方法的解釋:

Like commit() but allows the commit to be executed after an activity’s state is saved. This is dangerous because the commit can be lost if the activity needs to later be restored from its state, so this should only be used for cases where it is okay for the UI state to change unexpectedly on the user.

用我蹩腳的語法直譯一下就是:
使用的 commit方法是在Activity的onSaveInstanceState()之後呼叫的,這樣會出錯,因為onSaveInstanceState方法是在該Activity即將被銷燬前呼叫,來儲存Activity資料的,如果在儲存玩狀態後再給它新增Fragment就會出錯。解決辦法就是把commit()方法替換成 commitAllowingStateLoss()就行了,其效果是一樣的。或者有使用dialogfragment的show方法報此異常的可使用

getFragmentManager().beginTransaction().add(aaa, “aaa”).commitNowAllowingStateLoss();
dialogfragment的dismiss()方法則換乘dismissAllowingStateLoss();
之後崩潰日誌中就不會再報錯誤了.