Hi All,
今天收到反饋的一個(gè)問(wèn)題卑笨,說(shuō)單例里面報(bào)了一個(gè)空指針導(dǎo)致項(xiàng)目會(huì)crash掉,所以今天分析了一下候生,感覺(jué)有借鑒意義
原因
直觀的分析日志可以看到是因?yàn)閱卫锩娴囊粋€(gè)static
的參數(shù)config
為null
導(dǎo)致的問(wèn)題同眯。
正常流程
1、設(shè)備入口
2唯鸭、onCreate()
方法里面調(diào)用單例的
init方法把參數(shù)傳給單例 3须蜗、頁(yè)面里面需要單例的方法直接獲取這個(gè)單例 4、然后在退出登陸或者其他情況把單例
destory() `
分析問(wèn)題和猜測(cè)
- 問(wèn)題:按照正常的流程是不會(huì)出現(xiàn)
config
為空的問(wèn)題目溉,除非是單例銷(xiāo)毀了明肮。單例銷(xiāo)毀的可能性按照正常的流程會(huì)重新走入口頁(yè)面重新獲取conifg
不會(huì)有問(wèn)題。 - 猜測(cè):
App
切換到后臺(tái)后缭付,一段時(shí)間不操作柿估,再切回來(lái),很容易就發(fā)生崩潰(配置低的手機(jī)這種問(wèn)題出現(xiàn)更頻繁)陷猫。究其原因秫舌,是因?yàn)槌30褜?duì)象存儲(chǔ)在全局變量里面(這里是單例里面),而App
切換到后臺(tái)后绣檬,進(jìn)程很容易就被系統(tǒng)回收了足陨,下次切換回來(lái)的時(shí)候App
頁(yè)面再重建,但是系統(tǒng)重建的App
對(duì)于原來(lái)存儲(chǔ)的全局變量卻無(wú)能為力娇未。 - 結(jié)論:經(jīng)模擬和猜測(cè)相符(詳細(xì)復(fù)現(xiàn)步驟見(jiàn)下文)墨缘。
復(fù)現(xiàn)問(wèn)題
第一步:打開(kāi)App
到門(mén)禁流程中需要單例DataSourceInstance
的界面。
第二步:按Home
鍵退出應(yīng)用零抬。
第三步:使用DDMS-Stop Process
結(jié)束進(jìn)程镊讼。
第四步:回到項(xiàng)目應(yīng)用中,正常使用(注:現(xiàn)在處于一個(gè)新的Application
中平夜,沒(méi)有之前操作存儲(chǔ)的數(shù)據(jù)了) 復(fù)現(xiàn)了出現(xiàn)該崩潰蝶棋,驗(yàn)證了猜想。
解決辦法
1忽妒、不在進(jìn)入的入口頁(yè)進(jìn)行init
操作玩裙,放在Application
中初始化。(目前的處理辦法)
因?yàn)槊看?code>App被回收重建的時(shí)候都會(huì)執(zhí)行onCreate
方法锰扶。這樣就會(huì)避免這樣的問(wèn)題
2、本地存儲(chǔ)(不建議使用寝受,不具有實(shí)時(shí)性)
3坷牛、用dagger
進(jìn)行參數(shù)和對(duì)象的注入,不設(shè)置全局的變量很澄,動(dòng)態(tài)按需注入京闰。
原因和第一步一樣颜及,dagger
是在application
中init
的。當(dāng)頁(yè)面中需要注入的參數(shù)沒(méi)有就會(huì)new一個(gè)新的蹂楣。
4俏站、當(dāng)然還有其他的解決方案,歡迎討論痊土。