深夜记一个大坑:illegalStateException:can not perform this action after onSaveInstanceState

本文主要是介绍深夜记一个大坑:illegalStateException:can not perform this action after onSaveInstanceState,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

好吧,其实重点不在于这个Excpetion…

项目采用了MVP模式,有1个Activity,3个Fragment,通过Presenter来切换Fragment,其中,Presenter中创建并保存了这3个Fragment的实例(避免不断的重复创建新的实例)

我在用AlarmManager设置了一个闹铃提醒(其context 是MainActivity),
这个提醒会启动一个BroadcastReceiver,在这个BroadcastReceiver中,我需要去更新UI,,,
本来嘛,一开始,出于条件反射,就想使用Handler,然后,由于太懒(应该还是条件反射哈哈),用Handler实在是太麻烦了。
于是,我灵机一动(坑了自己一把),就想把Presenter写成单例这里写图片描述
然后就可以在BroadcastReceiver中调用到Presenter了,然后就可以轻易的更新UI!!
这里写图片描述
然后,然后,,
一切执行得很顺利,一直到我手贱打开app,退出app,又打开app,,,咦,怎么变空白了???
一时间感觉摸不着头脑,然后我试着切换到另一个Fragment,,,没错,出现了标题中的那个异常,W……T……F……这什么鬼,明明是在onCreate中执行commit的啊,,,好吧,然而明明并帮不了我
然后便上google到stackoverflow等站遨游一番。。
以下便是采集到的战果:

  • 在onResume中执行commit(3.0以前)
  • 在onPostResume中执行commit(3.0及以后)
  • 在onResumeFragments中执行commit
  • 重写onSaveInstanceState,让其实现为空
  • 还有著名的”用commitAllowStateLoss来替代commit“
  • 重写Activity的onBackPress方法

这么多方法,前后查找包括测试就花了2个多小时(包括很多无果的查找和测试)。。。。然并卵
于是,我继续到处搜查,
直到,,我看到了一篇文章说明的情况和我非常的相似:使用AlarmManager设置闹钟,AlarmActivity接收提醒并做UI更新(他是创建DialogFragment)……
好吧,看完一堆说明之后,我发现跟他还是 不!一!样!
不一样在什么地方呢,不一样在他是使用了上面提到的方法解决的。。

然后我就开始受不了,这这这世界是怎么了,怎么连google都解决不了了。。

然后,我想起了一句话:最难跳出的坑总是你自己设下的。。(好吧,这是我说的)

于是我不再google,开始自己一点一点的调试,在某个瞬间,突然觉得自己像傻逼一样:既然页面空白,那应该首先考虑到是不是Fragment没有初始化呢……(这个时候,我开始意识到真正的错误不是那个异常,而是有幕后黑手,而这个黑手就是我自己培养出来的。。)

然后,我测试了几个Fragment的onCreate方法和onDestroy方法,我打开app,关闭app,打开app,,果然不出我所料!这些方法都只执行了一遍!!

然后就想到一件原先意想不到的事情,Activity销毁后,Presenter单例并没有被销毁!!一测试果不其然。

到这里,就知道为什么报那个异常了吧:Fragment已经被销毁(执行了onDestroy方法,是 “After onSaveInstanceState”的),然后我重新打开app,并没有创建新的Fragment,就执行了commit

至于静态的Presenter为什么不会被销毁呢,好吧,我确实不知道,怪我孤陋寡闻。

然后随便一查,单例所造成的内存泄漏
看到这篇文章 说到静态变量销毁的2种情况:
1. 进程死了
2. 所在上下文从ClassLoader里面卸载了

至此,明白了此次bug造成的原因,,果然还是自己造的坑容易进难出。。。。

最后,我当然还是要使用单例的,毕竟对handler实在是反感,怎么办呢,现在就好办了,在Activity的onDestroy方法中释放Presenter即可。

这篇关于深夜记一个大坑:illegalStateException:can not perform this action after onSaveInstanceState的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/920733

相关文章

Unable to instantiate Action, goodsTypeAction, defined for 'goodsType_findAdvanced' in namespace '/

报错: Unable to instantiate Action, goodsTypeAction,  defined for 'goodsType_findAdvanced' in namespace '/'goodsTypeAction......... Caused by: java.lang.ClassNotFoundException: goodsTypeAction.......

com.google.gson.JsonSyntaxException:java.lang.IllegalStateException异常

用Gson解析json数据的时候,遇到一个异常,如下图: 这个异常很简单,就是你的封装json数据的javabean没有写对,你仔细查看一下javabean就可以了 比如:我的解析的代码是             Gson gson = new Gson();             ForgetJson rb = gson.fromJson(agResult.mstrJson, For

用ajax json给后台action传数据要注意的问题

必须要有get和set方法   1 action中定义bean变量,注意写get和set方法 2 js中写ajax方法,传json类型数据 3 配置action在struts2中

使用http-request 属性替代action绑定上传URL

在 Element UI 的 <el-upload> 组件中,如果你需要为上传的 HTTP 请求添加自定义的请求头(例如,为了通过身份验证或满足服务器端的特定要求),你不能直接在 <el-upload> 组件的属性中设置这些请求头。但是,你可以通过 http-request 属性来自定义上传的行为,包括设置请求头。 http-request 属性允许你完全控制上传的行为,包括如何构建请求、发送请

Flink整合Oozie Shell Action 提交任务带Kerberos认证

最近这段时间一直在忙新集群迁移,上了最新的cdh6.3.0 于是Flink 提交遇到了许多的问题,还好有cloudera License 有了原厂的帮助和社区的伙伴,问题解决起来快了不少。 集群具体情况是 CDH6.3.0 Flink1.8.1,整个数据平台全部组件都上了kerberos和ldap因为要过认证,所以任务提交方法我们选择统一Oozie提交任务,并且因为kerberos认证,还需要F

Servlet mapping specifies an unknown servlet name Action

看一下web.xml中<servlet-mapping>有没有配错

Activity状态保存【onSaveInstanceState和onRestoreInstanceState】

Activity的onSaveInstanceState() 和 onRestoreInstanceState()方法: 1. 基本作用:   Activity的 onSaveInstanceState() 和 onRestoreInstanceState()并不是生命周期方法,它们不同于 onCreate()、onPause()

【ssh学习笔记】struts2的action与Spring

//由struts-spring-plugin管理,不需要加@Resource,或在<span style="font-family: Arial; font-size: 14px; line-height: 26px;">applicationContext.xml</span>中也不需要配置该bean //需要注入的对象也不需要加@Resource public class JsonA

Android中常用Action

Android中常用Action 2010-08-10 14:07 标准的Activity Actions ACT ION_MAIN                              作为一个主要的进入口,而并不期望去接受数据 ACT ION_VIEW                            向用户去显示数据 ACT ION_ATTACH_

github中action作用和讲解

1,简介 GitHub Actions 是 GitHub 的一个自动化功能,它允许你在 GitHub 仓库中自动执行软件开发工作流程。你可以使用 GitHub Actions 来执行各种任务,比如: 自动测试:每当代码被推送到仓库时,自动运行测试来确保代码质量。持续集成:自动构建和部署代码,确保新的代码更改不会破坏现有功能。代码格式化:自动格式化代码,以保持代码风格的一致性。自动部署:将代