行程
為什麼要了解生命週期
Android 應用程式的生命週期是由 Android 框架進行管理,而不是由應用程式直接控制。
要讓使用者有好的使用經驗,Activity 需要在各個週期點上負責保管狀態、恢復狀態、傳送資料等工作。
Activity 的狀態
Android 的虛擬機(VM)是使用堆疊 (Stack based) 管理。主要有四種狀態:
Active (活動)
「Active」狀態是使用者啟動應用程式或 Activity 後,Activity 運行中的狀態。
Paused (暫停)
「Paused」狀態是當 Activity 暫時暗下來,退到背景畫面的狀態。
Stopped (停止)
「Stopped」狀態是有其他 Activity 正在執行,而這個 Activity 已經離開螢幕,不再動作的狀態。
透過長按「Home」鈕,可以叫出所有處於「Stopped」狀態的應用程式列表。
在「Stopped」狀態的 Activity,還可以透過「Notification」來喚醒。「Notification」會在後面章節中解說。
Dead (已回收或未啟動)
「Dead」狀態是 Activity 尚未被啟動、已經被手動終止,或已經被系統回收的狀態。
要手動終止 Activity,可以在程式中呼叫「finish」函式。我們在加入選單一章中已經提到過了。
如果是被系統回收,可能是因為記憶體不足了,所以系統根據記憶體不足時的回收規則,將處於「Stopped」狀態的 Activity 所佔用的記憶體回收。
記憶體不足時的行為
記憶體不足時,Dalvak 虛擬機會根據其記憶體回收規則來回收記憶體:
- 先回收與其他 Activity 或 Service/Intent Receiver 無關的行程(即優先回收獨立的Activity)
- 再回收處於「Stopped」狀態的其他類型 Activity(在背景等待的Activity)。最久沒有使用的 Activity 優先回收(比較官方的說法是 "根據 LRU 演算法...")
- 還不夠?回收 Service 行程
- 快不行啦,關掉可見的 Activity/行程
- 關閉當前的 Activity
當系統缺記憶體缺到開始「4. 關掉可見的 Activity/行程」時,大概我們換機子的時機也早該到啦!
觀察 Activity 運作流程
講了這麼多虛的,我們可以寫一些程式來直觀查看 Activity 的運作流程嗎?
當然可以。在上一章記錄與偵錯 (Log)中,我們學到的「Log」工具,正好可以在查看 Activity 的運作流程時派上用場。
打開「src/com/demo/android/bmi/Bmi.java」,在程式中加入一些「Log」記錄點:
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");
}
}
講解
我們為 Activity 的各個狀態加入了「Log」記錄訊息。當模擬器運行時,我們可以透過 「LogCat」工具來查看 Activity 所處在的狀態。
完整的 Activity 生命週期由「Create」狀態開始,由「Destroy」狀態結束。 建立(Create)時分配資源,銷毀(Destroy)時釋放資源。
當 Activity 運行到「Start」狀態時,就可以在螢幕上看到這個 Activity。相反地,當Activity 運行到「Stop」狀態時,這個 Activity 就會從螢幕上消失。
當使用者按下 Back 按鈕回到上一個 Activity 時,會先到 Restart 狀態,再到一般的 Start 狀態。
Activity 運作流程
由實際運行的記錄來看,我們可以歸納出所有 Android 應用程式都遵循的動作流程:
一般啟動
onCreate -> onStart -> onResume
呼叫另一個 Activity
onPause(1) -> onCreate(2) -> onStart(2) - onResume(2) -> onStop(1)
這是個先凍結原本的 Activity,再交出直接存取螢幕能力(Pause 狀態)的過程。 直到 Activity 2 完成一般啟動流程後,Activity 1 才會被停止。
回原 Activity
onPause(2) -> onRestart(1) -> onStart(1) -> onResume(1) -> onStop(2) -> onDestroy(2)
退出結束
onPause -> onStop -> onDestroy
回收後再啟動
onCreate -> onStart -> onResume
被回收掉的 Activity 一旦又重新被呼叫時,會像一般啟動一樣再次呼叫 Activity 的 onCreate 函式。
當我們使用「Android」手機一陣子,在手機上已經執行過多個應用程式。只要按下「Back」(返回)鍵,「Android」就會開啟最近一次開啟過的 Activity。
這時我們要是按下多次「Back」(返回)鍵,理論上遲早會返回到某個已經銷毀(Destroy)的 Activity。這時會發生什麼事呢?
如果應該開啟的 Activity 已經被回收了,那麼這個 Activity 會再次被建立(Create)出來。再次被建立出來的 Activity,當然會跟原本我們開啟過的 Activity 不一樣啦。
我們可以使用下章介紹到的「Preference」(偏好設定)等方法來記錄之前運作時的資料或設定。
參考資料
- Activity Cycle