標籤:android 生命週期 activity
應用程式(或Activity)執行的狀態稱為進程(progress)。在 Android作業系統中,每個應用程式都是一個進程。Android架構會維護一個唯一的Activity記錄堆棧,並觀察每個應用程式進程。同時,系統平台會依照系統的記憶體使用量情況和Activity的狀態來管理系統記憶體。Activity類別除了負責運行程式流程與作業系統介面組件外,最重要的就是它提供了開發人員控制進程生命週期的函數。
Android應用程式的生命週期是由Android架構進行管理的,而不是由應用程式自己直接控制。通常每一個應用程式(入口一般會是一個Activity的onCreate方法),都會佔據一個進程。當系統記憶體即將不足時,會依照優先順序順序自動進行進程的回收。
一個Activity類除了onCreate方法外,還預先定義了onPause(暫停進程時的行為)、onResume(繼續進程的行為)等基本行為。當從一個Activity切換到另外一個Activity的時候,原本的Activity將經過一連串的狀態改變。我們就可以在程式中添加一些各種狀態相對應的流程,每次Activity改變狀態時,就會執行相應的流程。
Activity的狀態
Android的虛擬機器是使用堆棧(Stack based)管理。主要有4種狀態:
- Active(活動)
- Paused(暫停)
- Stopped(停止)
- Dead(已回收或未啟動)
Active(活動)
Active狀態是使用者啟動應用程式或Activity後,Activity運行中的狀態。
在Android平台上,同一個時刻只會有一個Activity處於活動(Activity)或運行(Running)狀態。其他的Activity都處於未啟動(Dead)、停止(Stopped)或是暫停(Paused)狀態。
Paused(暫停)
Paused狀態是目前啟動並執行螢幕畫面暫時暗下來,退到背景畫面的狀態。
當我們使用“Toast”、“AlertDialog”或者來電話時,都會讓原本啟動並執行Activity退回為背景畫面。新出現的“Toast”、 “AlertDialog”等介面組件蓋住了原來的Activity介面。Activity處於Paused狀態時,使用者是無法與原Activity互動的。
Stopped(停止)
Stopped狀態是有其他Activity正在執行,而這個Activity已經離開螢幕,不再有進行中的狀態。
通過長按“首頁”鍵,可以調出所有處於Stopped狀態的應用程式。在Stopped狀態的Activity,還可以通過“Notification”來喚醒。
Dead(已回收或未啟動)
Dead狀態是Activity尚未被啟動或者被手動停止,或已經被系統自動回收的狀態。
要手動終止Activity,可以在程式中調用finish()函數。如果是被系統自動回收,則表明可能是系統記憶體不足了,所以系統根據記憶體不足的回收規則,將處於Stopped狀態的Activity所佔用的記憶體回收。
系統記憶體不足時的行為
當Android系統記憶體不足時,會根據以下的規則來回收記憶體:
- 先回收與其他Activity或Service/Intent Receiver無關的進程,即優先回收獨立的Activity
- 再回收處於Stopped狀態的其他類型的Activity(在背景等待的Activity)。最久沒有使用的Activity會被優先回收(比較官方的說法是根據“LRU演算法”)
- 還不夠?回收service進程
- 還不行?關掉可見的Activity/進程
- 關閉當前的Activity
當系統記憶體缺失到要關閉“可見的Activity/進程”時,那麼是不是要考慮下換個手機了。
觀察Activity運行流程
public class Bmi extends Activity { private static final String TAG = "Bmi"; public void onCreate(){super.onCreate(...);Log.v(TAG,"onCreate");} public void onStart() { super.onStart(); Log.v(TAG, "onStart"); } public void onResume() { super.onResume(); Log.v(TAG, "onResume"); } public void onPause() { super.onPause(); Log.v(TAG, "onPause"); } public void onStop() { super.onStop(); Log.v(TAG, "onStop"); } public void onRestart() { super.onRestart(); Log.v(TAG, "onReStart"); } public void onDestroy() { super.onDestroy(); Log.v(TAG, "onDestroy"); }}
上面的七個狀態又可以歸納成三組:
1. 資源分派(Create/Destroy)
完整的Activity 生命週期由”Create”狀態開始,由”Destroy”狀態結束。建立 (Create)時分配資源,銷毀(Destroy)時釋放資源。
2. 可見與不可見(Start/ReStart/Stop)
當Activity 運行到”Start”狀態時,就可以在螢幕上看到這個Activity。相反地,當 Activity 運行到”Stop”狀態時,這個Activity 就會從螢幕上消失。
當使用者按下Back 按鈕回到上一個Activity 時,會先到Restart 狀態,再到一般 的Start 狀態。
3. 使用者能否直接存取螢幕(Resume/Pause)
當有個Toast、AlertDialog、簡訊、電話等訊息亂入時,原來的Activity 會進入 “Pause”狀態,暫時放棄直接存取螢幕的能力,被中斷到背景去,將前景交給優先順序高的事件。當這些優先順序高的事件處理完後,Activity就改進入”Resume”狀態,此時又直接存取 螢幕。
實際函數名稱中都冠以On開頭命名的方法,Activity的生命週期狀態圖如下:
Activity運作流程
由實際啟動並執行記錄來看,我們可以歸納出所有Android 應用程式都遵循的動作流程:
一般啟動
- onCreate -> onStart -> onResume
啟動一個Activity 的基本流程是:分配資源給這個Activity(Create狀態),然後將Activity內容顯示到螢幕上(Start狀態)。在一切就緒後,取得螢幕的控制權(Resume狀態),使用者可以開始使用這個程式。
調用另一個Activity
- onPause(1) -> onCreate(2) -> onStart(2) - onResume(2) -> onStop(1)
這是個先凍結原本的Activity,再交出直接存取螢幕能力(Pause狀態)的過程。直 到Activity2完成一般啟動流程後,Activity1才會被停止。
返回原Activity
- onPause(2) -> onRestart(1) -> onStart(1) -> onResume(1) -> onStop(2) -> onDestroy(2)
在新的Activity2中,點選硬體的Back按鈕,回退到原本的Activity1。點Back按鈕可以回到原本的Activity。
退出結束
- onPause -> onStop -> onDestroy
如果程式中有直接呼叫”finish”函式來關閉Activity的話,系統假設我們很確定我們 在做什麼,因此會直接跳過先凍結(Freeze)的階段,暫停(Pause),停止(Stop),然後銷毀(Destroy)。
回收後再啟動
- onCreate ->onStart ->onResume
被回收掉的Activity一旦又重新被呼叫時,會像一般啟動一樣再次呼叫Activity的onCreate函數。這個和前面第一個步驟中的一般啟動是一樣的流程。
當我們使用”Android”手機一陣子,在手機上已經執行過多個應用程式。只要按下”Back” (返回)鍵,”Android”就會開啟最近一次開啟過的Activity。
這時我們要是多次按“返回”鍵,理論上遲早會返回到某個已經銷毀(Destroy)的Activity,這時會發生什麼呢?
如果應該開啟的Activity已經被回收了,那麼這個Activity會再次被建立(Create)出來,再次被建立出來的Activity,當然會跟原本我們開啟的Activity不一樣。
所以如果要讓再次被建立出來的Activity看起來跟原本開啟的一樣,那麼在Activity之間切換時,我們就要留意資料的儲存:最好在每次Activity運行到”onPause”或者”onStop”狀態時先儲存資料,然後在”onCreate”時將資料讀出來。
android知識點:Activity的生命週期