進(jìn)程和應(yīng)用生命周期

在大多數(shù)情況下,每個(gè) Android 應(yīng)用都在各自的 Linux 進(jìn)程中運(yùn)行。當(dāng)需要運(yùn)行應(yīng)用的一些代碼時(shí),系統(tǒng)會(huì)為應(yīng)用創(chuàng)建此進(jìn)程,并使其保持運(yùn)行,直到不再需要它且系統(tǒng)需要回收其內(nèi)存以供其他應(yīng)用使用。

應(yīng)用進(jìn)程的生命周期并不由應(yīng)用本身直接控制,而是由系統(tǒng)綜合多種因素來(lái)確定的,比如系統(tǒng)所知道的正在運(yùn)行的應(yīng)用部分、這些內(nèi)容對(duì)用戶的重要程度,以及系統(tǒng)中可用的總內(nèi)存量。這是 Android 非常獨(dú)特的一個(gè)基本功能。

應(yīng)用開發(fā)者必須了解不同的應(yīng)用組件(特別是 Activity、ServiceBroadcastReceiver)對(duì)應(yīng)用進(jìn)程的生命周期有何影響。這些組件使用不當(dāng)會(huì)導(dǎo)致系統(tǒng)在應(yīng)用進(jìn)程正執(zhí)行重要任務(wù)時(shí)將它終止。

進(jìn)程生命周期錯(cuò)誤的一個(gè)常見示例是當(dāng) BroadcastReceiver 在其 BroadcastReceiver.onReceive() 方法中接收到一個(gè) Intent 時(shí),它會(huì)啟動(dòng)一個(gè)線程,然后從該函數(shù)返回。一旦返回,則系統(tǒng)會(huì)認(rèn)為 BroadcastReceiver 不再處于活動(dòng)狀態(tài),因此不再需要其托管進(jìn)程(除非其中有其他應(yīng)用組件處于活動(dòng)狀態(tài))。因此,系統(tǒng)可能會(huì)隨時(shí)終止進(jìn)程以回收內(nèi)存,這樣會(huì)終止在進(jìn)程中運(yùn)行的衍生線程。要解決這個(gè)問(wèn)題,通??梢詮?BroadcastReceiver 調(diào)度 JobService,這樣系統(tǒng)就知道進(jìn)程中還有處于活動(dòng)狀態(tài)的任務(wù)正在進(jìn)行中。

為了確定在內(nèi)存不足時(shí)應(yīng)該終止哪些進(jìn)程,Android 會(huì)根據(jù)每個(gè)進(jìn)程中運(yùn)行的組件以及這些組件的狀態(tài),將它們放入“重要性層次結(jié)構(gòu)”。這些進(jìn)程類型包括(按重要性排序):

  1. A 前臺(tái)進(jìn)程 是用戶目前執(zhí)行操作所需的進(jìn)程。在不同的情況下,進(jìn)程可能會(huì)因?yàn)槠渌母鞣N應(yīng)用組件而被視為前臺(tái)進(jìn)程。如果以下任一條件成立,則進(jìn)程會(huì)被認(rèn)為位于前臺(tái):

系統(tǒng)中只有少數(shù)此類進(jìn)程,而且除非內(nèi)存過(guò)低,導(dǎo)致連這些進(jìn)程都無(wú)法繼續(xù)運(yùn)行,才會(huì)在最后一步終止這些進(jìn)程。通常,此時(shí)設(shè)備已達(dá)到內(nèi)存分頁(yè)狀態(tài),因此必須執(zhí)行此操作才能使用戶界面保持響應(yīng)。

  1. 可見進(jìn)程 正在進(jìn)行用戶當(dāng)前知曉的任務(wù),因此終止該進(jìn)程會(huì)對(duì)用戶體驗(yàn)造成明顯的負(fù)面影響。在以下條件下,進(jìn)程將被視為可見:

    • 它正在運(yùn)行的 Activity 在屏幕上對(duì)用戶可見,但不在前臺(tái)(其 onPause() 方法已被調(diào)用)。舉例來(lái)說(shuō),如果前臺(tái) Activity 顯示為一個(gè)對(duì)話框,而這個(gè)對(duì)話框允許在其后面看到上一個(gè) Activity,則可能會(huì)出現(xiàn)這種情況。
    • 它有一個(gè) Service 正在通過(guò) Service.startForeground()(要求系統(tǒng)將該服務(wù)視為用戶知曉或基本上對(duì)用戶可見的服務(wù))作為前臺(tái)服務(wù)運(yùn)行。
    • 系統(tǒng)正在使用其托管的服務(wù)實(shí)現(xiàn)用戶知曉的特定功能,例如動(dòng)態(tài)壁紙、輸入法服務(wù)等。

    相比前臺(tái)進(jìn)程,系統(tǒng)中運(yùn)行的這些進(jìn)程數(shù)量較不受限制,但仍相對(duì)受控。這些進(jìn)程被認(rèn)為非常重要,除非系統(tǒng)為了使所有前臺(tái)進(jìn)程保持運(yùn)行而需要終止它們,否則不會(huì)這么做。

  2. 服務(wù)流程 包含一個(gè)已使用 startService() 方法啟動(dòng)的 Service。雖然用戶無(wú)法直接看到這些進(jìn)程,但它們通常正在執(zhí)行用戶關(guān)心的任務(wù)(例如后臺(tái)網(wǎng)絡(luò)數(shù)據(jù)上傳或下載),因此系統(tǒng)會(huì)始終使此類進(jìn)程保持運(yùn)行,除非沒有足夠的內(nèi)存來(lái)保留所有前臺(tái)和可見進(jìn)程。

    已經(jīng)運(yùn)行了很長(zhǎng)時(shí)間(例如 30 分鐘或更長(zhǎng)時(shí)間)的服務(wù)的重要性可能會(huì)降位,以使其進(jìn)程降至下文所述的緩存 LRU 列表。這有助于避免超長(zhǎng)時(shí)間運(yùn)行的服務(wù)因內(nèi)存泄露或其他問(wèn)題占用大量?jī)?nèi)存,進(jìn)而妨礙系統(tǒng)有效利用緩存進(jìn)程。

  3. 緩存進(jìn)程 是目前不需要的進(jìn)程,因此,如果其他地方需要內(nèi)存,系統(tǒng)可以根據(jù)需要自由地終止該進(jìn)程。在正常運(yùn)行的系統(tǒng)中,這些是內(nèi)存管理中涉及的唯一進(jìn)程:運(yùn)行良好的系統(tǒng)將始終有多個(gè)緩存進(jìn)程可用(為了更高效地切換應(yīng)用),并根據(jù)需要定期終止最早的進(jìn)程。只有在非常危急(且具有不良影響)的情況下,系統(tǒng)中的所有緩存進(jìn)程才會(huì)被終止,此時(shí)系統(tǒng)必須開始終止服務(wù)進(jìn)程。

    這些進(jìn)程通常包含用戶當(dāng)前不可見的一個(gè)或多個(gè) Activity 實(shí)例(onStop() 方法已被調(diào)用并返回)。只要它們正確實(shí)現(xiàn)其 Activity 生命周期(詳情請(qǐng)見 Activity),那么當(dāng)系統(tǒng)終止此類流程時(shí),就不會(huì)影響用戶返回該應(yīng)用時(shí)的體驗(yàn),因?yàn)楫?dāng)關(guān)聯(lián)的 Activity 在新的進(jìn)程中重新創(chuàng)建時(shí),它可以恢復(fù)之前保存的狀態(tài)。

    這些進(jìn)程保存在偽 LRU 列表中,列表中的最后一個(gè)進(jìn)程是為了回收內(nèi)存而終止的第一個(gè)進(jìn)程。此列表的確切排序政策是平臺(tái)的實(shí)現(xiàn)細(xì)節(jié),但它通常會(huì)先嘗試保留更多有用的進(jìn)程(比如托管用戶的主屏幕應(yīng)用、用戶最后看到的 Activity 的進(jìn)程等),再保留其他類型的進(jìn)程。還可以針對(duì)終止進(jìn)程應(yīng)用其他政策:比如對(duì)允許的進(jìn)程數(shù)量的硬限制,對(duì)進(jìn)程可持續(xù)保持緩存狀態(tài)的時(shí)間長(zhǎng)短的限制等。

在決定如何對(duì)進(jìn)程進(jìn)行分類時(shí),系統(tǒng)會(huì)參考進(jìn)程中當(dāng)前活動(dòng)的所有組件中最重要的級(jí)別。請(qǐng)參閱 Activity、ServiceBroadcastReceiver 文檔,詳細(xì)了解這些組件各自對(duì)進(jìn)程的整體生命周期有何影響。每個(gè)類的文檔都詳細(xì)介紹了它們對(duì)應(yīng)用的整個(gè)生命周期有何影響。

進(jìn)程的優(yōu)先級(jí)也可能因從屬于進(jìn)程的其他依賴項(xiàng)而提升。例如,如果進(jìn)程 A 已通過(guò) Context.BIND_AUTO_CREATE 標(biāo)記綁定到 Service,或在使用進(jìn)程 B 中的 ContentProvider,則進(jìn)程 B 的分類始終至少和進(jìn)程 A 一樣重要。

參考:
https://developer.android.com/guide/components/activities/process-lifecycle

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容