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

本文针对FragmentTransaction在特定场景下出现的“Cannot perform this action after onSaveInstanceState”错误进行了深入剖析。通过对比commit()与commitAllowingStateLoss()方法,解释了在Activity状态已保存的情况下尝试提交FragmentTransaction时产生的问题。并给出了正确的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天在运行项目的时候突然出了如标题的错误,大写的懵逼!!!然后,将 FragmentTransaction 的 commit() 方法换成了 commitAllowingStateLoss 就OK了(不过下文中会告诉你不建议这么做),不过,不明所以,就花了一些时间看了看源码,并且找了几篇还不错的博客,记录在此。


想了想,还是先从现象说起吧,以倒推的方式来进行,这个其实比较直观一些。

现象:就如大部分app一样,首页会有一个底部的导航栏,在点击设置的menu的时候,如果没有登录就让用户去登录,然后登录成功后会在 MainActivity 的 onActivityResult 中动态添加一个设置的 fragment,那么问题就来了,就在添加后并且 commit 后报错了。

解决:将 FragmentTransaction 的 commit() 方法换成了 commitAllowingStateLoss 。

源码理解: FragmentTransaction的commit和commitAllowingStateLoss的区别
如果不耐烦看整篇博客的话可以直接看到最后的总结:ok,到这里,真相总算大明,当使用commit方法时,系统将进行状态判断,如果状态(mStateSaved)已经保存,将发生”Can not perform this action after onSaveInstanceState”错误。
这里我就不贴源码了,毕竟在上篇博客中已经很全了(而且复制别人写过的东西感觉很没意思啊,感谢作者)。

总之如果看到这里,其实问题基本就可以解决了,至少项目不会报错了,不过,我是真的不太明白为什么会这样,这到底是什么意思!


深入的理解
不是很理解源码中判断的保存到底是指的什么。一开始看到博客中的总结,以为是指 fragment 的保存,这其实就是个很大的错误,我想了一下就否决掉了,毕竟按照我的逻辑而言设置的 fragment 是绝对没有保存过得,除非我的 MainActiivty 销毁重建了,不过那样的话导致的错误也就不是标题的错误了,而是 fragment 重叠的问题了。

于是真的找到了一篇让我读了不下于五遍的博客(没错,我就是传说中的菜鸟程序猿=-=)Fragment Transactions和Activity状态丢失,万分感谢作者让我学到了不少。

如果你和我一样读懂了这篇文章那么就不用看我下面说的了,如果不是很懂,那么就可以看看我的总结是否正确:上文中所谓的保存,其实指的是Activity的保存,那么自然而然就想到了 onSaveInstance 方法,这个方法就是用来保存 Activity 状态的。可是这和 onSaveInstance 有什么关系呢?在聊关系之前,先了解下 onSaveInstance 是在什么时候调用的 activity 中的 onSaveInstanceState方法的调用时机,很明显除了 home 键选择程序/ home 键退到后台,我的情况属于从当前的 Activity 跳转到另外一个 Activity,那么 onSaveInstance 自然就调用了。

结合 状态丢失 的这篇博文,可以知道 onSaveInstance 是在 onPose 和 onStop 之间调用的,google认为状态丢失是一件非常重要的事情,文中说不惜一切代价的告诉用户,这一点我从直接抛出异常就体验到了,宁愿异常,也不愿意放过这个隐藏的问题。那么在 Activity 的onStop 方法调用之前就已经把状态保存了,那么在 onActivityResult 中的commit 方法自然就无法被保存起来了,异常就是这么来的。(建议可以认真看完 状态丢失 这篇博文,还可以了解到 3.0 前后 Activity 的一些变化)

真正的解决办法:在文章的最后三个建议中,其实真正的解决方法就是 建议一 ,建议在在FragmentActivity的onResumeFragments()函数或者Activity的onPostResume()函数中提交,而建议二,其实可以算是一个忠告,建议三就是不建议使用的,这种方法忽略了用户体验。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值