Hi All,
今天收到反馈的一个问题,说单例里面报了一个空指针导致项目会crash掉,所以今天分析了一下,感觉有借鉴意义
原因
直观的分析日志可以看到是因为单例里面的一个static
的参数config
为null
导致的问题。
正常流程
1、设备入口
2、onCreate()
方法里面调用单例的
init方法把参数传给单例 3、页面里面需要单例的方法直接获取这个单例 4、然后在退出登陆或者其他情况把单例
destory() `
分析问题和猜测
- 问题:按照正常的流程是不会出现
config
为空的问题,除非是单例销毁了。单例销毁的可能性按照正常的流程会重新走入口页面重新获取conifg
不会有问题。 - 猜测:
App
切换到后台后,一段时间不操作,再切回来,很容易就发生崩溃(配置低的手机这种问题出现更频繁)。究其原因,是因为常常把对象存储在全局变量里面(这里是单例里面),而App
切换到后台后,进程很容易就被系统回收了,下次切换回来的时候App
页面再重建,但是系统重建的App
对于原来存储的全局变量却无能为力。 - 结论:经模拟和猜测相符(详细复现步骤见下文)。
复现问题
第一步:打开App
到门禁流程中需要单例DataSourceInstance
的界面。
第二步:按Home
键退出应用。
第三步:使用DDMS-Stop Process
结束进程。
第四步:回到项目应用中,正常使用(注:现在处于一个新的Application
中,没有之前操作存储的数据了) 复现了出现该崩溃,验证了猜想。
解决办法
1、不在进入的入口页进行init
操作,放在Application
中初始化。(目前的处理办法)
因为每次App
被回收重建的时候都会执行onCreate
方法。这样就会避免这样的问题
2、本地存储(不建议使用,不具有实时性)
3、用dagger
进行参数和对象的注入,不设置全局的变量,动态按需注入。
原因和第一步一样,dagger
是在application
中init
的。当页面中需要注入的参数没有就会new一个新的。
4、当然还有其他的解决方案,欢迎讨论。