下文将分兩部分來讨論Activity的生命周期,參照任玉剛老師的《Android開發藝術探索》一書,結合所學進行總結擴充。
- 典型情況下的生命周期
- 異常情況下的生命周期
下圖表示正常情況下Activity的生命周期過程。
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIn5GcuYmY1kjMkZWMhZGOxgTO3UWY3UTYwcTYhZmY5ATOxUzYfdWbp9CXt92Yu4GZjlGbh5SZslmZxl3Lc9CX6MHc0RHaiojIsJye.png)
image.png
下面是7個生命周期:
/* onCreate:
* 表示Activity正在被建立,執行一些初始化工作
* (如:調用 setContentView 加載界面布局資源,初始化Activity所需資料等);
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
/* onStart:
* 表示Activity正在被啟動,這時Activity已經可見(對應用可見),
* 隻不過還在背景,使用者還看不到;
*/
@Override
protected void onStart() {
super.onStart();
}
/* onResume:
* 表示Activity已經出現在前台,使用者可見;
*/
@Override
protected void onResume() {
super.onResume();
}
/* onPause:
* 表示Activity正在停止,可以執行存儲資料、停止動畫等不太耗時的工作
* (因為新活動的onCreate方法要在舊活動的onPause執行完才執行,
* 為了不影響使用者體驗,要求這個過程盡可能在很短時間内完成);
*/
@Override
protected void onPause() {
super.onPause();
}
/* onStop:
* 表示Activity即将停止,可以做一些稍微重量級的工作,同樣不能太耗時;
*/
@Override
protected void onStop() {
super.onStop();
}
/* onDestory:
* 表示Activity即将被銷毀,執行回收工作和資源釋放。
*/
@Override
protected void onDestroy() {
super.onDestroy();
}
/* onRestart:
* 表示Activity正在重新啟動,
* 執行順序為:onPause → onStop → onRestart → onStart → onResume
*/
@Override
protected void onRestart() {
super.onRestart();
}
上面描述的是Activity正常情況下的生命周期,這裡再結合我們平常使用手機過程中的一些操作,具體說明一下其生命周期過程:
- 初次啟動一個Activity,回調情況:
Android筆記(一) | Activity的生命周期 - 從Activity A 打開新的Activity B,B活動回調情況:onPause -> ( Activity B 啟動)-> onStop 。這裡還有一種特殊情況,當新啟動的Activity采用透明主題時,目前Actvity不會回調onStop方法。(見補充說明1)
- 從A活動切換到B活動,再回到A活動,期間A活動沒有調用finish()方法。A活動回調情況:
Android筆記(一) | Activity的生命周期 - 按back鍵退出Activity A,A活動回調情況:(見補充說明2)
Android筆記(一) | Activity的生命周期 - 息屏,然後亮屏,回調情況:
Android筆記(一) | Activity的生命周期
實踐出真知,這些過程都可以自己寫個簡單的Demo驗證一下,印象更深刻一些。
補充說明:
- onStart 和 onStop,onResume 和 onPause 這兩個配對的回調是具有不同意義的,onStart 和 onStop 是從Activity是否可見這個角度來回調的,而onResume 和 onPause則是從Activity是否位于前台來回調的,在實際使用過程中沒有其他明顯差別。說明:onStart(背景可見)-> onResume(前台可見)-> onPause(背景可見)-> onStop(背景也不可見)。
個人觀點:上述執行個體2的原因是在回調onStop方法前,Activity A在背景是可見的,隻不過不在前台無法與使用者發生互動,如果回調了onStop,背景的Activity A也不可見了,那麼Activity B的透明背景之後是預設的白色背景,視覺上會顯得十分尴尬,個人覺得這麼設計也是為了優化使用者體驗吧。
- 預設情況下,按back鍵,會回調Activity的 onDestroy 方法,銷毀目前執行個體。
- 從Activity A跳轉到 Activity B的過程中,先回調 A 的onPause方法,然後建立Activity B,然後才回調 A 的 onStop 方法(在上面的2,3兩個執行個體中都能發現),是以,不要在onPause方法中執行耗時的操作,以盡快啟動Activity B,使得使用者擁有流暢的使用體驗。
根據手機使用過程中的常見情形,我們從兩種情況來讨論Activity在異常模式下的生命周期:
情況1: 資源相關的系統配置發生改變導緻Activity被殺死并重新建立
最常見的情形就是手機螢幕發生旋轉時,由于系統配置發生改變,在預設情況下(即沒有特殊設定),Activity會被銷毀并重新建立。其生命周期如下圖:
與正常生命周期相比,多了資料的儲存和恢複這兩個過程。當Activity在異常情況下終止時,系統會調用onSaveInstanceState方法将Activity的狀态儲存為一個Bundle對象,這個對象會在Activity重新建立後傳遞給onRestoreInstanceState方法和onCreate方法,這個方法的調用時機是在onStop之前,與onPause沒有既定的時序關系。當Activity被重新建立後,系統會調用onRestoreInstanceState,将onSaveInstanceState方法儲存的Bundle對象作為參數,取出其中的資料進行恢複,這個方法的調用時機是在onStart之後。根據這一點,我們可以判斷onRestoreInstanceState方法是否被調用或者onCreate方法中的Bundle參數是否為null來确定Activity是否被重建。
每個View都有自己的onSaveInstanceState方法和onRestoreInstanceState方法,以根據不同View的需求來恢複不同的資料,例如:TextView恢複了自身文本的選中狀态和文本内容。
前面提到,onSaveInstanceState方法儲存的資料會傳遞給onRestoreInstanceState方法和onCreate方法,也就是說,進行資料恢複時,有兩種方式,一種是在onCreate方法中進行,一種是在onRestoreInstanceState方法中進行。但是在onCreate方法中進行資料恢複的話,需要考慮Activity是正常啟動的還是被重建的,如果是正常啟動,那麼onCreate(Bundle onSaveInstanceState)中的onSaveInstanceState參數是null。當然,官方文檔是建議采用onRestoreInstanceState方法來恢複資料的。
前面強調了在預設情況下,系統配置發生改變時,Activity會被重新建立,也就是說,這是可以改變的。我們知道,在AndroidManifest檔案中會對每個Activity進行注冊,而在Activity标簽下有android:configChanges這個屬性。這個屬性下包含很多值,與一些系統配置相對應,當我們希望在某個系統配置改變時不重建這個Activity,就可以在configChanges屬性中添加對應的值。
常用的有:
1.orientation:螢幕方向發生改變,比如手機螢幕旋轉;
2.locale:裝置的本地位置發生了改變,一般指切換了系統語言;
3.keyboardHidden:鍵盤的可通路性發生了改變,例如使用者調出了鍵盤。
<activity android:name=".MainActivity"
android:configChanges="orientation|locale|keyboardHidden">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
補充:
1. 當我們指定了configChanges屬性時,如果指定的系統配置發生改變,不會重建Activity,但是會調用Activity的 onConfigurationChanged 方法,我們可以根據自己的需求重寫這個函數。
情況2:資源記憶體不足導緻低優先級的Activity被殺死
這種情況不友善模拟,但生命周期和情況1是相同的。Activity的優先級由高到低如下:
1.前台Activity;
2.可見但非背景Activity——例如被Dialog遮擋的的Activity;
3.背景Activity——執行了onStop的Activity。
如果一個程序中沒有四大元件在執行,那麼這個程序将很快被殺死,是以,一些背景工作最好是放在Service中進而提高優先級,不至于輕易被系統殺死。
下一篇:
Android筆記 | Activity的啟動模式