作為一個(gè)Android應(yīng)用開發(fā)人員, 自不必說, Activity是我們應(yīng)用的門面, 我們90%的工作都圍繞它進(jìn)行, 用它來呈現(xiàn)內(nèi)容, 用它來與用戶交互...
那么我們真的了解Activity嗎? 它到底怎么來, 又怎么沒的呢? 它是怎么加載布局, 怎么呈現(xiàn)內(nèi)容的呢? 它們之間是如何交互的呢??? 太多的問題.
讓我們先從Activity的生命周期開始我們的探索之旅吧.
1, 疑問
- Activity生命周期回調(diào)有哪些? 分別對(duì)應(yīng)做什么?
- Back和Home鍵退出Activity有什么區(qū)別?
- 切換屏幕會(huì)發(fā)生什么? 怎么處理?
- 從Activity A啟動(dòng)Activity B會(huì)發(fā)生什么? 再從B啟動(dòng)A呢?
2, 探索
帶著這些疑問, 開始我們的探索吧.
首先, 我們根據(jù)官方文檔中的Activity生命周期圖:

寫一個(gè)簡單的Demo程序, 有AActiviy和BActivity兩個(gè)Activity, 分別都有兩個(gè)按鈕, 啟動(dòng)A和B. 然后在二者的各個(gè)生命周期和其他對(duì)外回調(diào)中加上log信息. 做如下幾個(gè)實(shí)驗(yàn), 查看log輸出.
Demo源碼已上傳github, 源碼地址.
以下實(shí)驗(yàn)中, AActivity和BActivity的啟動(dòng)模式均為標(biāo)準(zhǔn)模式. 關(guān)于launch mode, 后續(xù)會(huì)結(jié)合task和back stack來一起探索.
2.1, 正常啟動(dòng)Activity, Back退出, 再回來
首先, 我們看下正常啟動(dòng)AActivity的log輸出:

可以看出果然如lifecycle圖所示, onCreate -- onStart -- onResume 的線路創(chuàng)建了一個(gè)新的AActivity實(shí)例 AActivity@429ea620.
Back退出:

點(diǎn)擊back鍵時(shí), 依照 onPause -- onStop -- onDestroy 的順序AActivity@429ea620銷毀了.
注意: 退出時(shí)并沒有調(diào)用onSaveInstanceState.
再回來:

很明顯, 是一個(gè)新的AActivity實(shí)例AActivity@4295cd70創(chuàng)建了.
2.2, Home退出, 再回來
點(diǎn)擊Home鍵的log輸出:

沒有onDestory, 且調(diào)用了onSaveIInstanceState.
再回來:

因?yàn)闆]有銷毀, 所以再次進(jìn)入時(shí)走restart流程, onRestart -- onStart -- onResume.
2.4, 旋轉(zhuǎn)屏幕
我們旋轉(zhuǎn)以下手機(jī)屏幕看看會(huì)發(fā)生什么:

可以看到AActivity銷毀重建了~~
注意: 這里在銷毀重建的過程中, 銷毀時(shí)調(diào)用了onSaveInstanceState, 而重建時(shí)調(diào)用了onRestoreInstanceState.
我們?cè)趍anifest文件中給AActivity加上configChanges屬性:
<activity
android:name=".lifecycle.AActivity"
android:label="A-Activity"
android:configChanges="orientation|keyboardHidden|screenSize">
</activity>
再試下:

請(qǐng)忽略AActivity的hash碼. 可以看到這次AActivity在轉(zhuǎn)屏?xí)r并沒有重建, 而是調(diào)用了onConfigurationChanged.
2.5, A, B之間的切換
1, 從A發(fā)起一個(gè)Intent啟動(dòng)B

1, 新啟動(dòng)了一個(gè)BActivity的實(shí)例.
2, AActivity的onPause之后才開始啟動(dòng)BActivity.
3, BActivity的onResume之后, AActivity才調(diào)用onStop.
2, 從B再發(fā)起一個(gè)Intent啟動(dòng)A

會(huì)再新建一個(gè)AActivity的實(shí)例, 而非使用原來的實(shí)例(因?yàn)槲覀兊膌aunch mode是默認(rèn)的標(biāo)準(zhǔn)模式).
流程和A啟動(dòng)B完全一樣.
3, 從B按Back鍵到A

1, AActivity@429dadb0重啟了
2, BActivity銷毀了.
3, 和A啟動(dòng)B類似, B onPause之后A 重啟, A重啟完onResume之后, B onStop -- onDestroy.
結(jié)論
Activity的生命周期如官方圖所示, 從onCreate -- onStart -- onResume 創(chuàng)建, 對(duì)應(yīng)onPause -- onStop -- onDestory銷毀.
-
這六個(gè)關(guān)鍵回調(diào)構(gòu)成三個(gè)區(qū)間:
- 完整生命期: onCreate -- onDestory
- 可見周期: onStart -- onStop
- 可操作周期: onResume -- onPause
Back鍵會(huì)銷毀Activity, Home鍵Activity會(huì)進(jìn)入Stop狀態(tài).
onSaveInstanceState和onRestoreInstanceState不是生命周期回調(diào), 不是必須調(diào)用的.
可以理解為onSaveInstanceState是系統(tǒng)認(rèn)為可能會(huì)因?yàn)閮?nèi)存不夠或是Configuration改變等銷毀Activity時(shí)用來存儲(chǔ)Activity狀態(tài)的, 故而在Back鍵銷毀時(shí)Activity并不會(huì)調(diào)用onSaveInstanceState, 因?yàn)橄到y(tǒng)認(rèn)為這是用戶主動(dòng)銷毀的.
對(duì)于轉(zhuǎn)屏的處理, 我們可以在onSaveInstanceState和onRestoreInstanceState中處理Activity重建的狀態(tài)恢復(fù). 或是配置configChanges屬性, 在onConfigurationChanges處理Configuration變化.
從A啟動(dòng)B時(shí)(或者說Activity切換時(shí)), 是A的onPause執(zhí)行完, 才會(huì)開始B的onCreate, 所以要避免在onPause回調(diào)中執(zhí)行耗時(shí)操作, 以免切換不流暢.
以上的生命周期分析, 實(shí)際上是Activity的較為簡單的表現(xiàn), 實(shí)際場景中會(huì)結(jié)合Activity的launch mode, taskAffinity, activity屬性, Intent flag等綜合考慮.