java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
在使用Fragment的過程中,常常會遇到在Activity的onSaveInstanceState方法調(diào)用之后,操作commit或者popBackStack而導(dǎo)致的crash.
因為在onSaveInstanceState方法之后的操作狀態(tài)可能會丟失,因此Android framework默認會拋出一個異常.
對于commit方法來說,單純避免這個異常很簡單,使用commitAllowingStateLoss方法即可.但是popBackStack以及 popBackStackImmediate也都會檢查state(checkStateLoss),特別需要注意的是Activity的 onBackPressed方法
onBackPressed的調(diào)用時機:
* targetSdkVersion <= 5,在onKeyDown中調(diào)用
* targetSdkVersion > 5,在onKeyUp中調(diào)用
onSavedInstanceState的調(diào)用時機(如果調(diào)用的話):
* 一定在onStop之前
* 可能在onPause之前,也可能在onPause與onStop之間
需要注意的是: onSavedInstanceState方法不一定會調(diào)用,只有在Activity因為某些原因而被Framework銷毀,并且之后還需要重新創(chuàng)建的情況,才需要調(diào)用(例如:旋屏,或者內(nèi)存不足而回收返回棧中的某些Activity)
舉例:
* Activity A在前臺時,屏幕逐漸變暗直至鎖屏,那么A的onSavedInstanceState會被調(diào)用
* Activity A start Activity B,Activity A的onSavedInstanceState會被調(diào)用
* Activity A因為返回鍵或者finish調(diào)用而返回到上一個界面,那么A的onSavedInstanceState不會被調(diào)用
因此,當(dāng)onBackPressed在onSavedInstanceState方法之后調(diào)用,就一定會crash.解決方法主要有兩種:
重寫Activity的onSavedInstanceState()方法,并且注釋掉super調(diào)用.
這種方法能避免crash,但是它會導(dǎo)致整個Activity的狀態(tài)丟失.以DialogFragment為例,正常情況下,顯示的 DialogFragment在旋屏Activity重新創(chuàng)建之后,不需要我們處理,Dialog會自動顯示出來(參見 DialogFragment.onStart()),但是注釋掉Activity的onSavedInstanceState()方法之 后,Fragment狀態(tài)丟失,Activity重新創(chuàng)建之后,Dialog也就不會再顯示出來了.
更好且通用的做法:在調(diào)用commit,popBackStack以及onBackPressed方法之前,判斷 onSavedInstanceState()方法是否已經(jīng)執(zhí)行,并且onResume方法還沒有執(zhí)行,如果不是,那么直接操作,否則加入到 pending隊列,等待onResumeFragments或者onPostResume之后再執(zhí)行.
注意:不要在onResume中操作,因為這時候FragmentManager中的mStateSaved依然可能是true.(如果執(zhí)行順序是 onSavedInstanceState()->onPause()->onResume() 或者 onPause()->onSavedInstanceState()->onResume());
public void endPaintingPager(int index) {if (mFirstLevel == PAINTING_PAGER) {mFirstLevel = PAINTER_START;if (!mIsStateSaved) {getSupportFragmentManager().popBackStack();} else {mPopBackStackRunnable = new Runnable() {@Overridepublic void run() {getSupportFragmentManager().popBackStack();}};}}} @Overrideprotected void onPostResume() {super.onPostResume();if (mPopBackStackRunnable != null) {mPopBackStackRunnable.run();}}?
轉(zhuǎn)載于:https://www.cnblogs.com/reverie/p/5524124.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
以上是生活随笔為你收集整理的java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JS实现大整数乘法(性能优化、正负整数)
- 下一篇: 《构建之法》阅读笔记04