记一个State Loss断言
来源:互联网 发布:度娘软件下载 编辑:程序博客网 时间:2024/06/05 19:45
可能很多朋友在使用v4兼容包中的Fragment方法进行应用开发时都遇到过这种异常,诈一看调用栈,根本无从下手解决。下面我就详细分析下这个断言出现的原因和解决方法。
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)
原因
在Android的Honeycomb(3.0)版本开始,Activity只有在被stop后才可能会被杀死。而在Honeycomb版本之前,Activity在被pause后就有可能被杀死。系统在Activity被杀死之前会调用onSaveInstanceState()方法来保存当前Activity状态,也即相当于给当前Activity做一个快照,为了后续重新创建该Activity时可以恢复到被杀死前状态,保证用户体验。这就是说onSaveInstanceState方法在Honeycomb版本之前会在onPause之前调用,Honeycomb之后会在onStop之前调用。如下表所示:
在Honeycomb版本中Android引入的一个最大特性就是Fragment机制。而Fragment的管理需要用Activity中的FragmentManager通过事务提交的方式来变更当前Activity中Fragment的状态。如果程序在系统调用onSaveInstanceState之后进行了commit操作。那么这些状态就会被丢失,就会抛出异常。
v4兼容包,因为需要兼容3.0以前版本,如果commit在onPause后就抛出异常则对3.0以后版本来说就显得过于严格,所以兼容包对不同版本区别对待。具体表现如下表:
在3.0版本以前,使用v4的commit时,如果发生在onPause和onStop之间则不抛出异常,而直接做状态丢失处理。
举例
一个Activity的onCreate方法中包含如下代码: getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, new TestFragment()).commit();
在TestFragment的onCreate方法中增加一条打印日志,然后不断旋转屏幕,你会发现,每旋转一次屏幕TestFragment的打印日志都会比上次多打出一条。
这是因为,这个fragment的管理栈在Activity因为屏幕旋转被销毁时而由系统进行了保存,没旋转一次意味着Fragment栈中就多增加一个fragment,而这些fragment都会因为Activity的重建而自己本身也重新创建一次。
Tips:setRetainInstance方法可以防止Fragment重建
详细做法见:《Activity重建时保持Fragment状态的方法》
注意事项
注意事务提交时所处的Activity生命周期
避免在异步方法中使用事务
使用commitAllowingStateLoss
- 记一个State Loss断言
- Fragment Transactions & Activity State Loss
- Fragment Transactions & Activity State Loss
- Fragment Transactions & Activity State Loss
- Fragment Transactions & Activity State Loss
- Fragment Transactions & Activity State Loss
- Fragment Transactions & Activity State Loss
- Fragment Transactions & Activity State Loss
- Fragment Transactions & Activity State Loss
- Fragment Transaction 和 状态丢失 state loss
- Fragment提交transaction导致state loss异常
- 【转】Fragment Transactions & Activity State Loss
- Fragment提交transaction导致state loss异常
- Fragment提交transaction导致state loss异常
- Fragment提交transaction导致state loss异常
- Fragment提交transaction导致state loss异常
- Fragment提交transaction导致state loss异常
- Fragment提交transaction导致state loss异常
- 第七课:模型加载
- 自定义RelativeLayout
- JAVA操作Cookie工具类
- ios 分辨率 和物理大小
- Linux虚拟文件系统(内核初始化<二>)
- 记一个State Loss断言
- Linux虚拟文件系统(安装根文件系统)
- 曝各城市娶妻成本:深圳208万 程序员成为“妻奴”?
- Android传感器及使用方法
- Unity3D 播放MP4 的几种状态
- 【题解】最大零矩阵
- 【Django】Django命令(Manager.py)
- 有用的网址
- Linux虚拟文件系统之文件系统安装(sys_mount())