解决Can not perform this action after onSaveInstanceState异常总结
来源:互联网 发布:已备案域名怎么购买呢 编辑:程序博客网 时间:2024/06/03 21:03
转发请标明来源:http://blog.csdn.net/rflyee/article/details/74723891
上篇博客(这里这里)从源码层面分析了Can not perform this action after onSaveInstanceState异常产生的原因及流程,
接下来分析下该崩溃的设计原因以及如何避。
该异常的设计原因
大家都知道系统在内存吃紧时会按规则优先kill掉部分非前台activity,为了保证用户体验,系统在kill掉某个activity之前会先调用onSaveInstanceState,将当前window的一些重要状态以bundle的形式持久化,当用户回到该activity时,再通过onCreate、onRestoreInstanceState等方法恢复之前的状态,给用户一种该界面从来没有被kill的假象,从而提升用户体验。
那么问题来了,在系统onSaveXXX保存状态之后,一直到onRestoreXXX恢复状态之前,这段时间里程序如果再操作window,比如操作FragmentTransaction#commit()、操作FragmentDialog#show()/dismiss(),这些操作肯定没有保存在Bundle中,也就是下次onRestoreXXX恢复状态时是没有这些操作的,也就是所谓的lose state丢失状态,这样可能给用户一种前后不一致的用户体验。所以安卓团队为了“提升用户体验”,saveState之后再操作window就抛出一个IllegalStateException
异常,提醒(逼迫)开发者注意喽。
异常出现时机
commit()
before onPause()
OKcommit()
between onPause()
and onStop()
STATE LOSScommit()
after onStop()
EXCEPTION解决方法
FragmentActivity#onResumeFragments()
或者 Activity#onPostResume()
里使用。
RragmentAvtivity#onResume不可以,可以用FragmentAvtivity#
onResumeFragments 因为调用onResume时不能保证已经restore之前的state了(假设之前被kill,并saveState),参见 documentation。commitAllowingStateLoss
代替commit()。前者允许状态丢失,其他完全一样。也即控制着源码中
allowStateLoss(5)有blog说覆写onSaveInstanceState()但是不调用
super.onSaveInstanceState(outState);也能避免崩溃,知道原因后的你肯定灰常不建议这么做了(不然onSaveInstanceState还有啥用)。(个人测试,奇酷手机青春版,Android5.1,此方法无效)@Overrideprotectedvoid onSaveInstanceState(Bundle outState){//No call for super(). Bug on API Level > 11.}
试试这样解决,在BaseActivity中添加:
@Overrideprotected void onStart() { super.onStart(); // super.onStart();中将mStateSaved置为false mStateEnable = true;}@Overrideprotected void onResume() {// onPause之后便可能调用onSaveInstanceState,因此onresume中也需要置truemStateEnable = true;super.onResume();}@Overrideprotected void onSaveInstanceState(Bundle outState) {// super.onSaveInstanceState();中将mStateSaved置为truemStateEnable = false;super.onSaveInstanceState(outState);}@Overrideprotected void onStop() { // super.onStop();中将mStateSaved置为true mStateEnable = false;super.onStop();}/** * * activity状态是否处于可修改周期内,避免状态丢失的错误 * @return */public boolean isStateEnable() {return mStateEnable;}
之后调用修改状态的方法如fragmentDialog的show()、dismiss()方法等,则先判断状态是否可用。
if(isStateEnable()) {dialog.show();}
- 解决Can not perform this action after onSaveInstanceState异常总结
- 解决异常IllegalStateException: Can not perform this action after onSaveInstanceState
- IllegalStateException: Can not perform this action after onSaveInstanceState 异常解决
- Android 异常 IllegalStateException: Can not perform this action after onSaveInstanceState
- fragment 异常IllegalStateException: Can not perform this action after onSaveInstanceState
- Can not perform this action after onSaveInstanceState(fragment异常)
- can not perform this action after onsaveinstancestate异常
- android异常:Can not perform this action after onSaveInstanceState
- Can not perform this action after onSaveInstanceState 异常
- fragment/dialogfragment异常:Can not perform this action after onSaveInstanceState
- Android-异常处理-Can not perform this action after onSaveInstanceState
- Can not perform this action after onSaveInstanceState异常源码分析
- Fragment异常:Can not perform this action after onSaveInstanceState
- 解决IllegalStateException: Can not perform this action after onSaveInstanceState
- 解决IllegalStateException: Can not perform this action after onSaveInstanceState
- 解决IllegalStateException: Can not perform this action after onSaveInstanceState
- 解决IllegalStateException: Can not perform this action after onSaveInstanceState
- 解决IllegalStateException: Can not perform this action after onSaveInstanceState
- uboot 顶层Makefile 写全地址
- Open Vswitch 与 网络命名空间
- 开启基于JavaScript的机器学习之路 | 机器学习与JavaScript(一)
- 关于宏的概念,与函数的区别以及优缺点
- 文件处理函数
- 解决Can not perform this action after onSaveInstanceState异常总结
- 4. 什么是应用服务器?
- MTK lcm调试总结及解决思路
- Linux下git操作(一)——git基本命令
- AutoPOL 7.rar Aspen Plus 2004.2\ Aspen Plus 2004.2_完整版全功能好用\ fred.V7光线追迹软件\
- Spring横切面(advice),增强(advisor),切入点(PointCut)
- 怎样用grep匹配多个字符串? grep -E 'aaaaa|bbbbbb'
- mycat配置文件详解 安装指南
- CodeForces 652F. Ants on a Circle