跑Monkey的时候经常出来
一、
java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1341)
at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1352)
at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:595)
at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:574)
或者
二、
java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
at android.support.v4.app.FragmentManagerImpl.checkStateLoss(Unknown Source)
at android.support.v4.app.FragmentManagerImpl.popBackStackImmediate(Unknown Source)
at android.support.v4.app.FragmentActivity.onBackPressed(Unknown Source)
原因分析
从异常信息:java.lang.IllegalStateException:Can not perform this action after onSaveInstanceState得出是在onSaveInstanceState之后执行了某种不合法的操作导致.
在onSaveInstanceState之后试图提交FragmentTransaction。为了释放资源,Android系统可以终止非前台Activity所在的进程外的所有应用进程,Activity被回收前系统会回调onSaveInstanceState以保存Activity的状态;在onSaveInstanceState执行之后提交的FragmentTransaction将不会被系统记住,从用户的角度来说FragmentTransaction丢失了,Android为了保证用户体验避免状态的损失,抛出了IllegalStateException。
建议处理方法
1、在Activity的生命周期方法中提交FragmentTransaction须谨慎。
建议在onCreate()或者#onResumeFragments()、onPostResume()中执行,可以保证不会state loss。
至于onResume(),因为此时附属于Activity的Fragment还没到resume状态,意味着之前的状态有可能还保存着,此时不允许FragmentTransaction修改状态(具体可以参考onResume()方法的注释,及Activity.performResume()的代码)。
2、避免异步回调方法里面提交FragmentTransaction。
类似AsyncTask.onPostExecute()或者Handler.handleMessage(),这些方法调用的时候可能Activity.onStop()已被调用,没有一个简单的方法来判断Activity. onSaveInstanceState()是否已被调用(可以考虑自己加个状态变量)。
3、假如不在乎state loss,
使用FragmentTransaction.commitAllowingStateLoss()
吧。
FragmentTransaction.commitAllowingStateLoss()
与
FragmentTransaction.commit()
的区别是前者在发生 state loss的时候不会抛出异常。
4
、对于异常二,因为在onSaveInstanceState()之后执行
onBackPressed()抛出,这个暂时只在monkey中跑出来过,暂时的解决方法是将
onBackPressed()重载,try-catch处理。(如有更好的解决方案,请告知,谢谢)
@Override
public void onBackPressed() {
try {
super.onBackPressed();
} catch (Exception e) {
//一般这里应该把异常信息打印出来
finish();
}
}
另外说些相关的内容:
在Honeycomb(3.0)版本前Activity在onPause()后即可能被杀死,从Honeycomb开始则是在onStop后才可能被杀死。
所有版本在onPause()前FragmentTransaction.commit()都没有问题;Honeycomb(3.0)之前的版本在onPause()与onStop()之间FragmentTransaction.commit()会造成state loss,从Honeycomb开始在onPause()与onStop()之间提交则没有问题;所有版本在onStop()之后FragmentTransaction.commit()都会抛出异常。