DialogFragment出现java.lang.IllegalStateException: Can not perform this action after onSaveIns
这个异常存在我一个软件已经有数个版本之余了,在每次软件有更新提示时调用了自定义DialogFragment时会出现此异常然后软件闪退。
一开始我有搜索相关处理方法,但由于本人对Android的Activity生命周期概念没有理解透彻以及对DialogFragment的使用还比较浅,导致了这个BUG遗留至今,在今天晚上偶然碰到此篇CSDN文【使用自定义DialogFragment出现IllegalStateException: Can not perform this action after onSaveInstanceState异常】
文中对异常说得很详细,也给出了具体解决方法,我也沉下心好好去阅读:
onSaveInstanceState
首先要明白onSaveInstanceState这个方法的性质以及该调用它的时间
onSaveInstanceState()是在Activity将要被kill之前被调用,它会保存当前Activity的实例状态,以便在后来切回到此Activity时展现出原来的状态
一般会在以下场景下调用:
1.用户返回桌面按下HOME键时
2.打开此Activity时锁屏
3.横竖屏切换
4.Activity A 跳至Activity B时,可能会因为系统回收资源而要将A杀掉,也会调用onSaveInstanceState()
接着要说到Activity生命周期几个重要的环节:
在API 11之前:只能是在onPause()前调用onSaveInstanceState()
在API 11之后:只能保证是在onStop()前调用onSaveInstanceState(),就没有明确说明onSaveInstanceState()在onPasues()的前后顺序
因为此微小的生命周期变化,API 11之后如果是在onPause()与onStop()之间调用了,就会抛出IllegalStateException的异常。其实能触发此情况的场景非常少,但因为我在实现某项目里的Dialog这个功能时引用了handler 将会产生延迟,而且此handler我必须放在Activity一开始载入时就执行,导致卡在onPause()与onStop()这微妙的生命周期之间触发此异常。也因为这适时的巧合让我对生命周期有了更深的学习
解决方法:
只需要将此DialogFragment下的show()方法重写:将FragmentTransaction的commit替换成commitAllowingStateLoss (ommitAllowingStateLoss 在状态丢失时不会抛出任何异常)
@Override public void show(FragmentManager manager, String tag) { // super.show(manager, tag); FragmentTransaction ft = manager.beginTransaction(); ft.add(this, tag); ft.commitAllowingStateLoss(); }