處理程序與應用程式生命週期

在大多數情況下,每個 Android 應用程式都會在其專屬的 Linux 程序中執行。當應用程式需要執行部分程式碼時,系統會為該應用程式建立此處理程序,並持續執行,直到系統需要回收記憶體供其他應用程式使用,且該處理程序不再需要為止。

Android 的一項特殊且基本功能,是應用程式程序的生命週期「不會」直接由應用程式本身控管。而是由系統根據系統知道正在執行的應用程式部分、這些部分對使用者的重要性,以及系統可用的整體記憶體量來決定。

應用程式開發人員必須瞭解不同應用程式元件 (特別是 ActivityServiceBroadcastReceiver) 如何影響應用程式程序的生命週期。如果未正確使用這些元件,系統可能會在應用程式執行重要工作時終止其程序。

程序生命週期錯誤的常見例子是 BroadcastReceiver,當其在 BroadcastReceiver.onReceive() 方法中收到 Intent 時會啟動執行緒,然後從函式中傳回。返回後,系統會將 BroadcastReceiver 視為不再處於活動狀態,且不再需要其代管程序,除非其他應用程式元件在其中處於活動狀態。

因此,系統可隨時終止程序來回收記憶體,並在執行此操作時終止在程序中執行的衍生執行緒。解決這個問題的方法通常是從 BroadcastReceiver 排定 JobService,讓系統知道程序中正在進行中的作業。

為了決定在記憶體不足時要終止哪些程序,Android 會根據執行中的元件和這些元件的狀態,為每個程序排出重要性階層。依重要性排序,這些程序類型如下:

  1. 前景程序是指使用者目前正在執行的程序所需的程序。各種應用程式元件可能會以不同方式,讓包含的程序視為前景。如果符合下列任一條件,系統就會將程序視為處於前景:
  2. 系統中只有少數這類程序,而且只有在記憶體不足,連這些程序也無法繼續執行時,才會終止這些程序。一般來說,如果發生這種情況,表示裝置已達到記憶體分頁狀態,因此必須執行這項動作,才能讓使用者介面保持回應。

  3. 可見的程序會執行使用者目前瞭解的工作,因此終止該程序會對使用者體驗造成明顯的負面影響。在下列情況下,系統會將程序視為可見:
    • 它會執行 Activity,使用者可在畫面上看到該活動,但該活動並未處於前景 (已呼叫其 onPause() 方法)。舉例來說,如果前景 Activity 以對話方塊的形式顯示,讓先前的 Activity 顯示在後方,就可能會發生這種情況。
    • 它具有一個 Service,透過 Service.startForeground() 以前景服務執行 (這會要求系統將服務視為使用者知道的項目,或基本上視為可見的項目)。
    • 它會代管系統用於使用者熟悉的特定功能的服務,例如動態桌布或輸入法服務。

    在系統中執行的這些程序數量雖然不像前景程序那麼受限,但仍受到相對控制。這些程序被視為極為重要,除非需要維持所有前景程序執行,否則不會終止。

  4. 服務程序是指持有已透過 startService() 方法啟動的 Service。雖然使用者無法直接看到這些程序,但這些程序通常會執行使用者在意的作業 (例如背景網路資料上傳或下載),因此系統會一律保留這類程序,除非記憶體不足,無法保留所有前景和可見程序。

    已執行一段時間 (例如 30 分鐘以上) 的服務,可能會降級為次要,讓其程序降至快取清單。

    您可以使用 setForeground 建立需要長時間執行的程序。如果這是需要嚴格執行時間的週期性程序,可以透過 AlarmManager 排程。詳情請參閱「支援長時間執行的 worker」。這有助於避免長時間執行的服務使用過多資源 (例如記憶體外洩),導致系統無法提供良好的使用者體驗。

  5. 快取程序是指目前不需要的程序,因此當系統需要記憶體等資源時,可以視需要終止這些程序。在正常運作的系統中,只有這些程序會涉及資源管理。

    運作良好的系統會隨時提供多個快取程序,以便在應用程式之間切換,並視需要定期關閉快取的應用程式。只有在非常嚴重的情況下,系統才會終止所有快取的程序,並開始終止服務程序。

    由於系統隨時可能終止快取程序,因此應用程式應在快取狀態下停止所有工作。如果應用程式必須執行對使用者至關重要的作業,則應使用上述任一 API,在有效程序狀態下執行作業。

    快取的程序通常會保留一或多個使用者目前無法看到的 Activity 例項 (其 onStop() 方法已呼叫並傳回)。只要系統在終止這類程序時正確實作 Activity 生命週期,就不會影響使用者返回該應用程式的體驗。當相關活動在新程序中重建時,系統可以還原先前儲存的狀態。請注意,如果系統終止程序,系統不保證會呼叫 onDestroy()。詳情請參閱 Activity

    從 Android 13 開始,應用程式處理程序可能會在進入上述任一有效生命週期狀態前,收到有限或沒有執行時間。

    快取的程序會保留在清單中。這份清單的確切排序政策是平台的實作細節。一般來說,系統會嘗試保留較實用的程序,例如負責代管使用者主畫面應用程式或使用者最後看到的活動的程序,再保留其他類型的程序。您也可以套用其他程序終止政策,例如設定允許的程序數量硬性限制,或限制程序可持續快取的時間長度。

在決定如何分類程序時,系統會根據目前在程序中有效的所有元件中找到的最重要層級做出決定。如要進一步瞭解這些元件如何為程序和應用程式的整體生命週期做出貢獻,請參閱 ActivityServiceBroadcastReceiver 的說明文件。

程序的優先順序也可能會根據程序的其他依附元件而提高。舉例來說,如果程序 A 已繫結至具有 Context.BIND_AUTO_CREATE 標記的 Service,或是在程序 B 中使用 ContentProvider,則程序 B 的分類至少會與程序 A 一樣重要。