在我們操作程序時,Activity實例會在生命周期中的不同狀態間進行切換,Android系統會根據生命周期的不同階段喚起對應的回調函數來執行代碼。
一、理解生命周期

我們可以參考金字塔模型來理解,在一個activity的生命周期中,系統會像金字塔模型一樣去調用一系列的生命周期回調函數。Activity生命周期的每一個階段就像金字塔中的臺階。當系統創建了一個新的activity實例,每一個回調函數會向上一階移動activity狀態。處在金字塔頂端意味著當前activity處在前臺并處于用戶可與其進行交互的狀態。
當用戶退出這個activity時,為了回收該activity,系統會調用其它方法來向下一階移動activity狀態。在某些情況下,activity會隱藏在金字塔下等待(例如當用戶切換到其他app),此時activity可以重新回到頂端(如果用戶回到這個activity)并恢復用戶離開時的狀態。
這張圖詳細的展示了Activity的不同狀態以及狀態轉換的條件,對于理解生命周期至關重要。
根據activity的復雜度,也許不需要實現所有的生命周期方法。但了解每一個方法的回調時機并在其中填充相應功能,使得確保app能夠像用戶期望的那樣執行是很有必要的。如何實現一個符合用戶期待的app,我們需要注意下面幾點:
- 使用app的時候,不會因為有來電通話或者切換到其他app而導致程序crash。
- 用戶沒有激活某個組件時不會消耗寶貴的系統資源。
- 離開app并且一段時間后返回,不會丟失用戶的使用進度。
- 設備發生屏幕旋轉時不會crash或者丟失用戶的使用進度。
二、管理生命周期
Activity的生命周期函數:
public class Activity extends ApplicationContext {
protected void onCreate(Bundle savedInstanceState);
protected void onStart();
protected void onRestart();
protected void onResume();
protected void onPause();
protected void onStop();
protected void onDestroy();
}
啟動Activity,然后退出的完整周期函數調用過程:
08-13 21:48:47.472 12785-12785/com.zm.kingsoft.myapplication D/Activity﹕ onCreate
08-13 21:48:47.472 12785-12785/com.zm.kingsoft.myapplication D/Activity﹕ onStart
08-13 21:48:47.482 12785-12785/com.zm.kingsoft.myapplication D/Activity﹕ onResume
08-13 21:48:56.801 12785-12785/com.zm.kingsoft.myapplication D/Activity﹕ onPause
08-13 21:48:56.951 12785-12785/com.zm.kingsoft.myapplication D/Activity﹕ onStop
08-13 21:48:56.951 12785-12785/com.zm.kingsoft.myapplication D/Activity﹕ onDestroy
2.1. onCreate()
- 使用onCreate()初始化你的Activity:創建UI、為類的變量分配引用、綁定數據到控件、創建Service和線程。
- 為避免快速的創建和銷毀對象引發額外的垃圾回收,如果你的應用程序正常創建一套對象,建議它們在onCreate()中創建,因為在Activity的生命周期中它只被調用一次。
Note:onCreate()里面盡量少做事情,避免程序啟動太久都看不到界面。
2.2. onResume()
請注意,系統每次調用這個方法時,activity都處于前臺,包括第一次創建的時候以及當用戶從Paused狀態恢復activity時。所以,應該使用onResume()來初始化那些在onPause方法里面釋放掉的組件,并執行那些activity每次進入Resumed state都需要的初始化動作 (例如開始動畫與初始化那些只有在獲取用戶焦點時才需要的組件)
下面的onResume()的例子是與下面的onPause()例子相對應的。
@Override
public void onResume() {
super.onResume(); // Always call the superclass method first
// Get the Camera instance as the activity achieves full user focus
if (mCamera == null) {
initializeCamera(); // Local method to handle camera init
}
}
2.3. onPause()
當系統調用activity中的onPause(),從技術上講,意味著activity仍然處于部分可見的狀態.但更多時候意味著用戶正在離開這個activity,并馬上會進入Stopped狀態.
通常應該在onPause()回調方法里面做以下事情:
- 停止動畫或者是其他正在運行的操作,那些都會導致CPU的浪費.
- 提交在用戶離開時期待保存的內容(例如郵件草稿).
- 釋放系統資源,例如broadcast receivers, sensors (比如GPS), 或者是其他任何會影響到電量的資源。
例如, 如果程序使用Camera,onPause()會是一個比較好的地方去做那些釋放資源的操作。
@Override
public void onPause() {
super.onPause(); // Always call the superclass method first
// Release the Camera because we don't need it when paused
// and other activities might need to use it.
if (mCamera != null) {
mCamera.release()
mCamera = null;
}
}
通常,不應該使用onPause()來保存用戶改變的數據 (例如填入表格中的個人信息) 到永久存儲(File或者DB)上。僅僅當確認用戶期待那些改變能夠被自動保存的時候(例如正在撰寫郵件草稿),才把那些數據存到永久存儲 。
我們應該避免在onPause()時執行CPU-intensive 的工作,例如寫數據到DB,因為它會導致切換到下一個activity變得緩慢(應該把那些heavy-load的工作放到onStop()去做)。如果activity實際上是要被Stop,那么我們應該為了切換的順暢而減少在OnPause()方法里面的工作量。
Note:當activity處于暫停狀態,Activity實例是駐留在內存中的,并且在activity 恢復的時候重新調用。我們不需要在恢復到Resumed狀態的一系列回調方法中重新初始化組件。
2.4. onStop()
當activity調用onStop()方法, activity不再可見,并且應該釋放那些不再需要的所有資源。一旦activity停止了,系統會在需要內存空間時摧毀它的實例。極端情況下,系統會直接殺死我們的app進程,并不執行activity的onDestroy()回調方法, 因此我們需要使用onStop()來釋放資源,從而避免內存泄漏。(這點需要注意)
因為onPause()在activity處于前臺時調用,而onStop()會在后臺調用,不會影響用戶體驗,所以我們應該使用onStop()來執行那些耗時的釋放資源的操作,例如往數據庫寫信息。
即使系統會在activity stop時停止這個activity,它仍然會保存View對象的狀態(比如EditText中的文字) 到一個Bundle中,并且在用戶返回這個activity時恢復它們。
Note:無論什么原因導致activity停止,系統總是會在onStop()之前調用onPause()方法。
2.5 onDestroy()
大多數app并不需要實現這個方法,因為局部類的references會隨著activity的銷毀而銷毀,并且我們的activity應該在onPause()與onStop()中執行清除activity資源的操作。然而,如果activity含有在onCreate調用時創建的后臺線程,或者是其他有可能導致內存泄漏的資源,則應該在OnDestroy()時進行資源清理,殺死后臺線程。
除非程序在onCreate()方法里面就調用了finish()方法,系統通常是在執行了onPause()與onStop() 之后再調用onDestroy() 。在某些情況下,例如我們的activity只是做了一個臨時的邏輯跳轉的功能,它只是用來決定跳轉到哪一個activity,這樣的話,需要在onCreate里面調用finish方法,這樣系統會直接調用onDestory,跳過生命周期中的其他方法。
三、Activity事件方法鏈
- 3.1 啟動Activity
D/Activity﹕ onCreate
D/Activity﹕ onStart
D/Activity﹕ onResume
- 3.2 退出Activity
D/Activity﹕ onPause
D/Activity﹕ onStop
D/Activity﹕ onDestroy
- 3.3 Home鍵
程序進入后臺
D/Activity1﹕ onPause
D/Activity1﹕ onStop
重新啟動
D/Activity1﹕ onRestart
D/Activity1﹕ onStart
D/Activity1﹕ onResume
- 3.4 休眠/恢復
休眠
D/Log﹕ onPause
D/Log﹕ onSaveInstanceState
D/Log﹕ onStop
恢復
D/Log﹕ onRestart
D/Log﹕ onStart
D/Log﹕ onResume
- 3.5 旋轉屏幕
未重寫onConfigurationChanged方法()
D/Activity1﹕ onCreate
D/Activity1﹕ onStart
D/Activity1﹕ onResume
D/Activity1﹕ onPause
D/Activity1﹕ onSaveInstanceState
D/Activity1﹕ onStop
D/Activity1﹕ onDestroy
D/Activity1﹕ onCreate
D/Activity1﹕ onStart
D/Activity1﹕ onRestoreInstanceState
D/Activity1﹕ onResume
重寫onConfigurationChanged方法(未觸發生命周期方法)
D/Activity1﹕ onCreate
D/Activity1﹕ onStart
D/Activity1﹕ onResume
D/Activity1﹕ onConfigurationChanged
- 3.6 來電
顯示來電界面
D/Log﹕ onPause
D/Log﹕ onStop
關閉來電界面
D/Log﹕ onRestart
D/Log﹕ onStart
D/Log﹕ onResume
- 3.7 其他Activity
A-B
D/Activity1﹕ onPause
D/Activity2﹕ onCreate
D/Activity2﹕ onStart
D/Activity2﹕ onResume
D/Activity1﹕ onStop
A-B-A Back返回鍵
D/Activity2﹕ onPause
D/Activity1﹕ onRestart
D/Activity1﹕ onStart
D/Activity1﹕ onResume
D/Activity2﹕ onStop
D/Activity2﹕ onDestroy
四、與Activity生命周期結合的應用場景
- 4.1 與廣播(Broadcast)結合
在onResume注冊廣播(registerLinstener),在onPause注銷廣播(unregisterLinstener)。
例如:做"搖一搖"功能(傳感器)、監聽網絡變化,就可以在onResume中注冊監聽,在onPause里注銷掉,已節省資源提高效率。 - 4.2 與服務(Service)結合
在onStart綁定服務(bindService),在onStop中取消綁定(unbindService)。
例如:需要通過Service定時更新UI上的數據,而Activity的可見周期在onStart與onStop之間,那么就可以再onStart時啟動服務,在onStop時停止服務。為了節約系統資源,除了提高用戶體驗以外,開發人員應盡可能的優化程序。 - 4.3 與Cursor結合
使用managedQuery讓Activity幫你管理Cursor的生命周期,不用自己去close。但也有一些問題,補充兩篇文章:這里1、 這里2。 - 4.4 釋放資源
可以在onDestory中釋放一些資源。比如可以在onDestory時調用MediaPlayer的release。
相關文章:
Android官方培訓課程
理解Activity壽命
農民伯伯——Activity生命周期
兩分鐘徹底讓你明白Android Activity生命周期(圖文)!
[2015-8]