Fragment Or DialogFragment Can not perform this action after onSaveInstanceState
2015-09-26 01:44
507 查看
表现
可会造成app崩溃掉,具体日志如下:异常如下:
java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState at android.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1323) at android.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1341) at android.app.BackStackRecord.commitInternal(BackStackRecord.java:597) at android.app.BackStackRecord.commit(BackStackRecord.java:575) at android.app.DialogFragment.show(DialogFragment.java:230) at com.github.afeita.net.ext.TipsingNetCallback.onStart(TipsingNetCallback.java:55) at com.github.afeita.net.ext.AfeitaNet$3.onStart(AfeitaNet.java:567) at com.github.afeita.net.ext.request.CacheRequest.deliverOnStart(CacheRequest.java:260) at com.github.afeita.net.ExecutorDelivery$4.run(ExecutorDelivery.java:116) at android.os.Handler.handleCallback(Handler.java:733) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:136) at android.app.ActivityThread.main(ActivityThread.java:5001) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601) at dalvik.system.NativeStart.main(Native Method)
场景
这与不洽当的使用Fragment有关系,其实不光时DialogFragment,Fragment也有的。当:1、A activity页面中,需要异步通知B activity去更新或do something然后A再do 自己的(A)的something,而这让B do something洽好是切换Fragment的话(此时又回到A中自己在do something),那么就可以出现这个异常。
2、activity页面 某个原因要切换到后台中了,系统调用了onSaveInstanceState,此时之后异步任务来了,是需要show或dismiss一个DialogFragment也会报这个异常。
总之是:在onSaveInstanceState后执行了commit抛出的。
原因
上面的异常,跟踪上去是DialogFragment.show方法中报出来,好么查看下源码,这个show里用做什么,抛出这个异常的呢。public void show(FragmentManager manager, String tag) { mDismissed = false; mShownByMe = true; FragmentTransaction ft = manager.beginTransaction(); ft.add(this, tag); ft.commit(); //注意这里使用提commit }
解决方法:
对于肯定会出现这种需求的,比如网络请求访问弹出的加载中…提示DialogFragment。那么,不采用系统默认的show方法 显示对话框。采用自己用 FragmentTransaction控制,示例如下:
FragmentTransaction ft = activity.getFragmentManager().beginTransaction(); ft.add(dialogFragment, this.getClass().getSimpleName()); ft.commitAllowingStateLoss();//注意这里使用commitAllowingStateLoss()
根据google对ft.commitAllowingStateLoss方法的说明:Like commit() but allows the commit to be executed after an activity’s state is saved. This is dangerous because the commit can be lost if the activity needs to later be restored from its state, so this should only be used for cases where it is okay for the UI state to change unexpectedly on the user.
这个方法是允许activity在state状态改变保存(onSaveInstanceState) 时允许commit。。。但也许不是很洽当,因为当activity onRestoreInstanceState恢复状态时commit可能会被丢掉了。恢复不了那次的commit了。使用这个方法应该确保存页面状态的改变对用户无感时。一般可以确认是即使页面需要重新onRestoreInstanceState时上次commit丢失的也不用管时就可以用了。
注意前面虽然说的是DialogFragment,也是Fragment因为这点并不是DialogFrament特例它属于Fragment不能在onSaveInstanceState,普通的commit。
若DialogFragment使用了
ft.commitAllowingStateLoss,那么在关闭时使用
dialogFragment.dismissAllowingStateLoss。
相关文章推荐
- git commit
- 史上最全最强SpringMVC详细示例实战教程
- Eclipse中配置Servlet流程
- hdoj1798Tell me the area【求两圆相交部分的面积】
- java面试总结1
- bfs实现二叉树按行有序输出
- 链表反转
- Dijkstra算法
- 软件设计师&产品经理应常去的网站
- C++ | 段错误
- c++设计模式----迭代器模式iterator
- Cocos2d-x Lua 初步
- 为什么会有缓冲区溢出攻击专栏
- 《幸运大转盘》代码分享
- awakeFromNib与viewDidLoad的区别
- hdoj5120Intersection【求圆相交的面积】
- 3个线程顺序打印ABC10次
- POJ 2311 Cutting Game
- 链表的多项式加法链表的多项式加法
- Eclipse中servlet显示无法导入javax.servlet包问题的解决方案