java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState

04-28 13:18:45.030  19538-19538/com.chinatelematics.mb E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.chinatelematics.mb, PID: 19538
    java.lang.RuntimeException: Unable to resume activity {com.chinatelematics.mb/com.chinatelematics.mb.MenuActivityChina}: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
            at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2861)
            at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2890)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1311)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5117)
            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)
     Caused by: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
            at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1354)
            at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1372)
            at android.support.v4.app.FragmentManagerImpl.popBackStack(FragmentManager.java:499)
            at com.chinatelematics.compatTabLib.MyTabListener.onTabReselected(MyTabListener.java:64)
            at com.chinatelematics.compatTabLib.CompatTabHoneyComb.onTabReselected(CompatTabHoneyComb.java:143)
            at android.support.v7.app.ActionBarImplICS$TabWrapper.onTabReselected(ActionBarImplICS.java:571)
            at com.android.internal.app.ActionBarImpl.selectTab(ActionBarImpl.java:794)
            at android.support.v7.app.ActionBarImplICS.selectTab(ActionBarImplICS.java:282)
            at android.support.v7.app.ActionBarImplJB.selectTab(ActionBarImplJB.java:20)
            at com.chinatelematics.compatTabLib.TabHelperHoneyComb.setCurrentTab(TabHelperHoneyComb.java:59)
            at com.chinatelematics.mb.MenuActivityChina.setCurrentTab(MenuActivityChina.java:278)
            at com.chinatelematics.mb.MenuActivityChina.refreshTabTitle(MenuActivityChina.java:274)
            at com.chinatelematics.mb.MenuActivityChina.onResume(MenuActivityChina.java:137)
            at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1204)
            at android.app.Activity.performResume(Activity.java:5428)
            at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2851)
            at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2890)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1311)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5117)
            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时,经常会报这个错误.
关于这个错误在网上我找到了这样的一份解释:
http://www.androiddesignpatterns.com/2013/08/fragment-transaction-commit-state-loss.html
The exception was thrown because you attempted to commit a FragmentTransaction after the activity’s state had been saved, resulting in a phenomenon known as Activity state loss. the problem stems from the fact that these Bundle objects represent a snapshot of an Activity at the moment onSaveInstanceState() was called, and nothing more. That means when you call FragmentTransaction#commit() after onSaveInstanceState() is called, the transaction won’t be remembered because it was never recorded as part of the Activity’s state in the first place. From the user’s point of view, the transaction will appear to be lost, resulting in accidental UI state loss. In order to protect the user experience, Android avoids state loss at all costs, and simply throws an IllegalStateException whenever it occurs.
英语不怎么好,但是借助于工具,翻译了一下,大概的意思就是:Activity的onSaveInstanceState()方法被调用了,然后我们在那个时间点之后调用FragmentTransaction#commit()。
于是这个Fragment事务所执行后的操作将不会被记录(这个作为Activity一部分的Fragment不被记录),因此对用户来说这个
Fragment事务就丢失了,从而导致UI状态也丢失了。为了保证用户体验,Android就只是简单的抛出一个IllegalStateException,
避免状态丢失造成的不良影响.

这个是我测试报错的情景:软件在使用时主页是一个activity里面 有四个actionbar tab 控制四个fragment, 界面停留在某个界面,开通蓝牙与汽车相连,汽车获取手机的通讯录信息的提示框, 点击确定后, 重新回到软件界面时, crash了

追踪错误发现,报错的地方时 onResume方法中执行了一个刷新的方法,里面有一个 popBackStack方法,报错.注释掉这句话后,程序不报错.可以证明是这句话造成程序抛出异常.

原因: 在onresume方法中提交的事务造成事务状态的丢失,建议在FragmentActivity#onResumeFragments() or Activity#onPostResume(). 提交事务的状态.

还有一种解决方法,重写onSaveInstanceState()方法,里面做空实现(将super这一行去掉),可以避免报错.

我承认我对这个问题的理解不够透彻,如果有人比我这个解释的更透彻的,联系我

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值