? ? ? ? 最近參與一個(gè)美國(guó)的安卓項(xiàng)目,我參與時(shí)軟件的發(fā)行版本號(hào)已經(jīng)是4.1.1了。軟件代碼寫(xiě)得非常規(guī)范,代碼質(zhì)量也很高。說(shuō)明這是有一個(gè)非常有經(jīng)驗(yàn)的程序員開(kāi)發(fā)的一個(gè)項(xiàng)目。但是最近發(fā)現(xiàn)很多程序崩潰的報(bào)告(客戶用CrashLylics來(lái)跟蹤崩潰)。分析崩潰的原因,最終結(jié)論是Application對(duì)象里的數(shù)據(jù)變成了null。很多人會(huì)問(wèn),Application的數(shù)據(jù)怎么可能變成null呢?原因是Application對(duì)象(也就是安卓程序)在一定情況下會(huì)被操作系統(tǒng)銷毀。舉例來(lái)說(shuō),你的程序里面有個(gè)撥號(hào)按鈕,用戶點(diǎn)擊此按鈕時(shí),系統(tǒng)會(huì)切換到撥號(hào)程序,在這個(gè)時(shí)候,理論上你的安卓程序就有可能被銷毀,撥號(hào)完成后,系統(tǒng)會(huì)自動(dòng)回到撥號(hào)之前的Activity,你的程序會(huì)重新啟動(dòng),Activity會(huì)重新執(zhí)行生命周期的函數(shù),Application對(duì)象也會(huì)重新創(chuàng)建,Application里的數(shù)據(jù)消失了,因?yàn)榇嬖贏pplication里的數(shù)據(jù)沒(méi)有辦法在Application銷毀時(shí)進(jìn)行存儲(chǔ)。最終的結(jié)論是,不要試圖把在多個(gè)Activity里公用的數(shù)據(jù)存放在Application里,也不能存放在靜態(tài)全局變量里,一定要存的話,要把它作為一個(gè)內(nèi)存緩存,要考慮它變成null了時(shí)的情況(可以配合SharePreference或者文件緩存,弄個(gè)2級(jí)緩存)。
? ? ? ?這個(gè)一個(gè)很多很多安卓程序員都會(huì)犯的錯(cuò),究其原因是安卓的設(shè)計(jì)理念與眾不同。第一,安卓程序沒(méi)有類似iOS程序的程序退出回調(diào)(有一個(gè)只是開(kāi)發(fā)時(shí)可以用的)。第二,安卓的理念是,Activity等四大組件是可以直接跨進(jìn)程調(diào)用(復(fù)用)的,盡管通常開(kāi)發(fā)的安卓組件并不打算給別的程序使用。所以,按照安卓的設(shè)計(jì)理念,我們要盡量降低Activity等組件對(duì)外部狀態(tài)的依賴,讓每個(gè)Activity自給自足,需要的信息都通過(guò)啟動(dòng)時(shí)的Intent傳進(jìn)來(lái)。
? ? 重要的事情重復(fù)三遍,不要把在Applicaiton和靜態(tài)變量里存放全局狀態(tài),除非你準(zhǔn)備好了它變成null。