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

在大多數情況下,每個 Android 應用程式都會以各自的 Linux 程序執行。當部分程式碼需要執行並持續運作時,系統會為應用程式建立這項程序,直到系統需要收回其記憶體供其他應用程式使用,而不再需要該應用程式時。

Android 有一個特殊的根本功能,就是應用程式程序的生命週期「無法」直接控管應用程式本身。相對的,系統則會結合系統知道正在執行的應用程式部分、這些事項對使用者的重要性,以及系統內有多少記憶體可用,藉此判斷這些部分。

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

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

因此,系統可隨時終止程序以收回記憶體,而這麼做的話,就會終止程序中執行的已生成執行緒。這個問題的解決方法通常是從 BroadcastReceiver 排定 JobService,讓系統知道程序中有進行中的工作。

為了判斷記憶體不足時要終止哪些程序,Android 會根據執行中元件及其狀態,將每個程序歸類到重要階層結構。「重要性」的流程類型如下:

  1. 前景程序是使用者目前正在執行的操作。不同的應用程式元件可能會導致其包含的程序以不同方式視為前景。如果發生下列任一條件,程序即視為在前景執行:
  2. 系統中只會有這類程序,而且只有在記憶體不足時,也不會讓這些程序繼續運作,這些程序才會終止。一般而言,如果發生這種情況,裝置已進入記憶體分頁狀態,因此必須執行這項操作,讓使用者介面保持回應。

  3. 「可見程序」會執行使用者目前已經知道的工作,因此終止作業會對使用者體驗造成明顯的負面影響。只要符合下列條件,就能認定程序:
    • 應用程式正在執行可向使用者顯示的 Activity,但不在前景中 (已呼叫其 onPause() 方法)。舉例來說,如果將前景 Activity 顯示為對話方塊,讓使用者可在其後方看到先前的 Activity,就可能會發生這種情況。
    • 其具有透過 Service.startForeground() 以前景服務形式執行的 Service (要求系統將服務視為使用者瞭解的內容,或視為是可見的)。
    • 該服務代管的服務是針對使用者瞭解的特定功能,例如動態桌布或輸入法服務。

    在系統中執行的這些程序數量少於前景程序,但仍可受到相對控制。系統會將這些程序視為極為重要,除非這樣做,才能讓所有前景程序保持執行,否則不會終止。

  4. 服務程序是擁有已使用 startService() 方法啟動的 Service。雖然這些程序不會直接向使用者顯示,但其執行的是使用者所關注的操作 (例如背景網路資料上傳或下載),因此除非記憶體不足,無法保留所有前景和可見的程序,否則系統一律會執行這類程序。

    長時間執行的服務 (例如 30 分鐘以上) 可能會降低其重要性,讓其程序能捨棄至快取清單。

    您可以使用 setForeground 建立需要長期執行的程序。如果這是定期處理程序,需要嚴格執行,可透過 AlarmManager 排程。詳情請參閱支援長時間執行的工作站。這有助於避免長時間執行的服務使用過多資源,例如記憶體流失這類情況,可避免系統提供良好的使用者體驗。

  5. 「快取程序」目前並不需要,因此當其他位置需要記憶體等資源時,就可以視需要終止系統。在平常運作的系統中,是資源管理唯一涉及的程序。

    效能良好的系統隨時都具有多個快取程序,以便有效率地切換應用程式,並視需要定期終止快取的應用程式。只有在極嚴重的情況下,系統才能到達所有快取程序遭到終止,且必須開始終止服務程序的時間點。

    由於系統隨時都可以終止快取程序,因此應用程式在處於快取狀態時,應停止所有工作。如果使用者必須執行重要工作,應用程式則應使用上述 API,從啟用的程序狀態執行工作。

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

    自 Android 13 起,應用程式程序進入上述任一有效生命週期狀態之前,可能會接收到有限或完全沒有執行時間。

    快取程序會保存在清單中。此清單的確切排序政策是平台的實作詳細資料。一般而言,它會嘗試在其他類型的程序之前,先保留更實用的程序,例如代管使用者主畫面應用程式的程序,或使用者所看到的上次活動。您也可以套用其他終止程序的政策,例如限制允許的程序數量,或是限製程序可持續快取的時間。

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

系統可能也會根據程序擁有的其他依附元件,提高程序的優先順序。舉例來說,如果程序 A 以 Context.BIND_AUTO_CREATE 旗標繫結至 Service,或是在程序 B 中使用 ContentProvider,則處理 B 的分類一律至少和程序 A 一樣重要。