最近 無意當(dāng)中看到一道面試題是關(guān)于Activity異常情況下的生命周期分析,感覺自己還有所欠缺蚀瘸,隨即在書中尋找完整答案庶橱,特記錄如下苏章。
常見的異常情況有兩種,資源相關(guān)的系統(tǒng)配置發(fā)生改變以及系統(tǒng)內(nèi)存不足時(shí)泉孩,Activity就會被殺死
情況1:資源相關(guān)的系統(tǒng)配置發(fā)生改變導(dǎo)致Activity被殺死并重新創(chuàng)建
在默認(rèn)情況下寓搬,如果我們的Activity不做特殊處理县耽,那么當(dāng)系統(tǒng)配置發(fā)生改變后,Activity就會被銷毀并重新創(chuàng)建唾琼,其生命周期如下圖:
當(dāng)系統(tǒng)配置發(fā)生改變后锡溯,Activity會被銷毀祭饭,其onPause叙量,onStop,onDestroy均會被調(diào)用悠咱,由于Activity是在異常情況下終止的析既,系統(tǒng)會調(diào)用onSaveInstanceState來保存當(dāng)前Activity的狀態(tài)谆奥。
如圖:當(dāng)豎屏切換到橫屏?xí)r,測試log如下:
當(dāng)由橫屏切換到豎屏的時(shí)候宰译,測試log如下:
由此我們可以看出沿侈,當(dāng)系統(tǒng)配置發(fā)生改變后缀拭,Activity會被銷毀,其中onPause咙好,onStop褐荷,onDestory均會被調(diào)用,同時(shí)由于Activity是在異常情況下終止的葵第,系統(tǒng)會調(diào)用onSaveInstanceState來保存當(dāng)前Activity的狀態(tài)合溺。由上圖我們可以看出,onSaveInstanceState調(diào)用時(shí)機(jī)是在onStop之前棠赛,需要說明的是這個(gè)方法只會出現(xiàn)在Activity被異常終止的情況下,正常情況下系統(tǒng)不會回調(diào)這個(gè)方法鼎俘。當(dāng)系統(tǒng)重建的時(shí)候會調(diào)用onRestoreInstanceState這個(gè)方法贸伐,并且把Activity銷毀時(shí)onSaveInstanceState方法所保存的Bundle對象作為參數(shù)同時(shí)傳遞給onRestoreInstanceState和onCreate方法怔揩,因?yàn)槲覀兛梢酝ㄟ^onCreate和onRestoreInstanceState方法來判斷Activity是否被重建了,如果被重建了伏伐,那么我們就可以取出之前保存的數(shù)據(jù)并恢復(fù)藐翎,從上圖我們可以看出实幕,onRestoreInstanceState的調(diào)用時(shí)機(jī)是在onStart之后。
同時(shí)末贾,我們知道onSaveInstanceState和onRestoreInstanceState方法當(dāng)中凰锡,系統(tǒng)為我們做了一定得恢復(fù)工作掂为。當(dāng)Activity在異常情況下需要重新創(chuàng)建時(shí),系統(tǒng)會默認(rèn)為我們保存當(dāng)前的Activity的視圖結(jié)構(gòu)勇哗,并且在Activity重啟后為我們恢復(fù)這些數(shù)據(jù)。比如文本框中用戶輸入的數(shù)據(jù)抄谐,ListVIew滾動(dòng)的位置等派歌。這些View相關(guān)的狀態(tài)系統(tǒng)都能夠默認(rèn)為我們恢復(fù)酌呆。
關(guān)于保存和恢復(fù)View層次結(jié)構(gòu)踩麦,系統(tǒng)的工作流程是這樣的:首先Activity被意外終止時(shí)祠锣,Activity會調(diào)用onSaveInstanceState去保存數(shù)據(jù),然后Activity會委托Window去保存數(shù)據(jù)蓬推,接著Window再委托它上面的頂級容器去保存數(shù)據(jù)沸伏。頂層容器是一個(gè)ViewGroup馋评,一般來說它可能是DecorView留特。最后頂層容器再去意義通知它的子元素來保存數(shù)據(jù),這樣整個(gè)數(shù)據(jù)保存過程就完成了糊渊『睾龋可以發(fā)現(xiàn)躏鱼,這就是一種典型的委托思想染苛,上層委托下次躯概,父容器委托子元素去處理一件事情娶靡。
針對onSaveInstanceState方法還需要有一點(diǎn)說明姿锭,那就是系統(tǒng)只會在Activity即將被銷毀并且有機(jī)會重新顯示的情況下才會調(diào)用它。當(dāng)Activity正常銷毀的時(shí)候懂傀,系統(tǒng)不會調(diào)用onSaveInstanceState恃泪,因?yàn)楸讳N毀的Activity不可能再次被顯示贝乎。比如我們上文提到的旋轉(zhuǎn)屏幕所造成的Activity異常銷毀览效,這個(gè)過程和正常停止Activity是不一樣的锤灿,因?yàn)樾D(zhuǎn)屏幕后辆脸,Activity被銷毀的同時(shí)會立刻創(chuàng)建Activity實(shí)例啡氢,這個(gè)時(shí)候Activity有機(jī)會再次立刻展示术裸,所以系統(tǒng)要進(jìn)行數(shù)據(jù)存儲亭枷。這里可以簡單地這么理解奶栖,系統(tǒng)只在Activity異常終止的時(shí)候才會調(diào)用onSaveInstanceState和onRestoreInstanceState來存儲和恢復(fù)數(shù)據(jù)门坷,其他情況不會觸發(fā)這個(gè)過程。
情況2:資源內(nèi)存不足導(dǎo)致低優(yōu)先級的Activity被殺死
這種情況冻晤,不是很好模擬绸吸,但是其數(shù)據(jù)存儲和恢復(fù)過程和情況1完全一致,這里我們描述一下Activity的優(yōu)先級情況锦茁,Activity按照優(yōu)先級從高到低码俩,可以分為如下三種:
1)前臺Activity——正在和用戶交互的Activity,優(yōu)先級最高
2)可見但是非前臺Activity——比如Activity中彈出了一個(gè)對話框稿存,導(dǎo)致Activity可見但是位于后臺無法和用戶直接交互
3)后臺Activity——已經(jīng)被暫停的Activity瓣履,比如執(zhí)行了onStop袖迎,優(yōu)先級最低
當(dāng)系統(tǒng)內(nèi)存不足時(shí),系統(tǒng)就會按照上述優(yōu)先級去殺死目標(biāo)Activity所在的進(jìn)程辜贵,并且后續(xù)通過onSaveInstanceState和onRestoreInstanceState來存儲和恢復(fù)數(shù)據(jù)脯宿,如果一個(gè)進(jìn)程中沒有四大組件在執(zhí)行连霉,那么這個(gè)進(jìn)程將很快被系統(tǒng)殺死嗡靡,比較好的方法是將后臺工作放入Service中從而保證進(jìn)程有一定的優(yōu)先級讨彼,這樣就不會輕易地被系統(tǒng)殺死哈误。
####歡迎關(guān)注公共號
![](https://upload-images.jianshu.io/upload_images/3258163-a5d26661ebcd43b0.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)