先上 Google 提供的經典圖,是對 Activity 生命周期各個階段之間導航轉換的直觀展現。
Activity 類提供了六個核心回調:onCreate()、onStart()、onResume()、onPause()、onStop()和onDestroy()。
說明#
- 在正常的情況下,Activity 從啟動到結束會按以下的順序經歷整個生命周期:onCreate ()->onStart ()->onResume ()->onPause ()->onStop ()->onDestory ()。
- onCreate (): 系統首次創建 Activity 的時候觸發,可以做一些初始化的工作,比如初始化 Activity 所需要的數據,還有調用 setContentView 加載界面布局資源。
- onRestart ():表示 Activity 正在重新啟動。一般情況下,當當前 Activity 從不可見重新變為可見狀態時,onRestart 就會被調用。這種情形一般是用戶行為導致的,比如用戶按 Home 鍵切換到桌面或打開了另一個新的 Activity,接著用戶又回到了這個 Actvity。
- onStart (): 表示 Activity 正在被啟動,即將開始,這時 Activity 已經出現了,** 但是還沒有出現在前臺,無法與用戶交互。** 這個時候可以理解為 Activity 已經顯示出來,但是我們還看不到。
- onResume (): 表示 Activity 已經可見了,並且出現在前臺並開始活動。需要和 onStart () 對比,onStart 的時候 Activity 還在後臺,onResume 的時候 Activity 才顯示到前臺。
- onPause (): 表示 Activity 正在停止,仍可見,正常情況下,緊接著 onStop 就會被調,onPause 中不能進行耗時操作,會影響到新 Activity 的顯示。因為 onPause 必須執行完,新的 Activity 的 onResume 才會執行。
- onStop (): 表示 Activity 即將停止,不可見,位於後臺。可以做稍微重量級的回收工作,同樣不能太耗時。
- onDestory (): 表示 Activity 即將銷毀,這是 Activity 生命周期的最後一個回調,可以做一些回收工作和最終的資源回收。
幾種普遍情況#
從 A 頁面 Activity 跳轉到 B 頁面 Activity,然後關閉 B 頁面 Activity,回到 A 頁面 Activity#
- 針對開啟的 B 頁面 Activity,第一次啟動,回調如下:onCreate ()->onStart ()->onResume ()
- 用戶打開 B 頁面 Activiy 的時候,A 頁面的 Activity處於不可見的回調如下:onPause ()->onStop ()
- 再次從 B 頁面回到 A 頁面原 Activity 時,A 頁面從不可見到可見回調如下:onRestart ()->onStart ()->onResume ()
- 按 back 鍵回退時,B 頁面 Activity 回調如下:onPause ()->onStop ()->onDestory ()
- 按 Home 鍵切換到桌面後又回到 A 頁面該 Actitivy,回調如下:onPause ()->onStop ()->onRestart ()->onStart ()->onResume ()
- 調用 finish () 方法後,回調如下:onDestory ()(以在 onCreate () 方法中調用為例,不同方法中回調不同,通常都是在 onCreate () 方法中調用)
Activity 的三種運行狀態#
Resumed(活動狀態)#
又叫 Running 狀態,這個 Activity 正在屏幕上顯示,並且有用戶焦點。這個很好理解,就是用戶正在操作的那個界面。
Paused(暫停狀態)#
這是一個比較不常見的狀態。這個 Activity 在屏幕上是可見的,但是並不是在屏幕最前端的那個 Activity。比如有另一個非全屏或者透明的 Activity 是 Resumed 狀態,沒有完全遮蓋這個 Activity。
Stopped(停止狀態)#
當 Activity 完全不可見時,此時 Activity 還在後台運行,仍然在內存中保留 Activity 的狀態,並不是完全銷毀。這個也很好理解,當跳轉的另外一個界面,之前的界面還在後台,按回退按鈕還會恢復原來的狀態,大部分軟體在打開的時候,直接按 Home 鍵,並不會關閉它,此時的 Activity 就是 Stopped 狀態。
部分流程分支#
- 啟動 Activity: onCreate ()—>onStart ()—>onResume (),Activity 進入運行狀態。
- Activity 退居後台:當前 Activity 轉到新的 Activity 界面或按 Home 鍵回到主屏: onPause ()—>onStop (),進入停滯狀態。
- Activity 返回前臺: onRestart ()—>onStart ()—>onResume (),再次回到運行狀態。
- Activity 退居後台,且系統內存不足, 系統會殺死這個後台狀態的 Activity(此時這個 Activity 引用仍然處在任務棧中,只是這個時候引用指向的對象已經為 null),若再次回到這個 Activity, 則會走 onCreate ()–>onStart ()—>onResume ()(將重新走一次 Activity 的初始化生命周期)
- 鎖屏:onPause ()->onStop ()
- 解鎖:onStart ()->onResume ()
橫豎屏下切換#
第一種情況,銷毀當前的 Activity:#
在橫豎屏切換的過程中,Activity 會先銷毀後重建,也應該避免這種情況。
這裡有兩個回調:
- onSaveInstanceState 和 onRestoreInstanceState。
- 在 Activity 由於異常情況下終止時,系統會調用 onSaveInstanceState 來保存當前 Activity 的狀態。這個方法的調用是在 onStop 之前,它和 onPause 沒有既定的時序關係,該方法只在 Activity 被異常終止的情況下調用。當異常終止的 Activity 被重建以後,系統會調用 onRestoreInstanceState,並且把 Activity 銷毀時 onSaveInstanceState 方法所保存的 Bundle 對象參數同時傳遞給 onRestoreInstanceState 和 onCreate 方法。因此,可以通過 onRestoreInstanceState 方法來恢復 Activity 的狀態,該方法的調用時機是在 onStart 之後。其中 onCreate 和 onRestoreInstanceState 方法來恢復 Activity 的狀態的區別: onRestoreInstanceState 回調則表明其中 Bundle 對象非空,不用加非空判斷。onCreate 需要非空判斷。建議使用 onRestoreInstanceState。
- 簡單來說,這個過程 Activity 的生命周期為:onPause ()->onSaveInstanceState ()-> onStop ()->onDestroy ()->onCreate ()->onStart ()->onRestoreInstanceState->onResume ()
第二種情況,當前的 Activity 不銷毀,但是我們需要設置 Activity 的屬性:#
可以通過在 AndroidManifest 文件的 Activity 中指定如下屬性:
<activity
android:name=".activity.VideoDetailActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:screenOrientation="portrait"/>
通過回調下面的方法,避免橫豎屏切換的時候 Activity 的銷毀和重建:
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
當資源不足的時候,保留 Activity 的優先級順序:#
- 前臺 Activity—— 正在和用戶交互的 Activity,優先級最高。
- 可見但非前臺 Activity—— 比如 Activity 中彈出了一個對話框,導致 Activity 可見但是位於後臺無法和用戶交互。
- 後臺 Activity—— 已經被暫停的 Activity,比如執行了 onStop,優先級最低。