一 進(jìn)程生命周期
Android 系統(tǒng)會盡量長時間地保持應(yīng)用進(jìn)程仇祭,用戶應(yīng)用退出后醋奠,如果沒有主動把進(jìn)程 kill 掉贱纠,該進(jìn)程還會在系統(tǒng)中緩存莫换,這樣用戶再次啟動 App 時霞玄,會加速啟動。隨著打開的應(yīng)用越來越多拉岁,系統(tǒng)內(nèi)存會變得不足(Out of Memory)坷剧,為了新建進(jìn)程或運(yùn)行更重要的進(jìn)程,最終需要移除舊進(jìn)程來回收內(nèi)存喊暖。 為了確定保留或終止哪些進(jìn)程惫企,系統(tǒng)會根據(jù)進(jìn)程中正在運(yùn)行的組件以及這些組件的狀態(tài),將每個進(jìn)程放入“重要性層次結(jié)構(gòu)”中陵叽。 必要時狞尔,系統(tǒng)會首先消除重要性最低的進(jìn)程,然后是重要性略遜的進(jìn)程巩掺,依此類推偏序,以回收系統(tǒng)資源。LowMemoryKiller 機(jī)制就是系統(tǒng)用于判定是否需要?dú)⑦M(jìn)程和殺哪些進(jìn)程的一個機(jī)制胖替。
系統(tǒng)內(nèi)進(jìn)程優(yōu)先級分 5 級研儒。
-
前臺進(jìn)程 (Foreground process)
用戶當(dāng)前操作所必需的進(jìn)程豫缨。如果一個進(jìn)程滿足以下任一條件,即視為前臺進(jìn)程:
- 包含用戶正在交互的 Activity(已調(diào)用 Activity 的 onResume() 方法)
- 包含某個 Service端朵,后者綁定到用戶正在交互的 Activity
- 包含正在“前臺”運(yùn)行的 Service(已調(diào)用 startForeground())
- 包含正執(zhí)行一個生命周期回調(diào)的 Service(onCreate()好芭、onStart() 或 onDestroy())
- 包含正執(zhí)行其 onReceive() 方法的 BroadcastReceiver
-
可見進(jìn)程(Visible process)
沒有任何前臺組件、但仍會影響用戶在屏幕上所見內(nèi)容的進(jìn)程冲呢。 如果一個進(jìn)程滿足以下任一條件栓撞,即視為可見進(jìn)程:
- 托管不在前臺、但仍對用戶可見的 Activity(已調(diào)用
onPause()
方法)碗硬。例如,如果前臺 Activity 啟動了一個對話框瓢颅,允許在其后顯示上一 Activity恩尾,則有可能會發(fā)生這種情況。 - 托管綁定到可見(或前臺)Activity 的 Service挽懦。
可見進(jìn)程被視為是極其重要的進(jìn)程翰意,除非為了維持所有前臺進(jìn)程同時運(yùn)行而必須終止,否則系統(tǒng)不會終止這些進(jìn)程信柿。
- 托管不在前臺、但仍對用戶可見的 Activity(已調(diào)用
-
服務(wù)進(jìn)程 (Service process)
正在運(yùn)行已使用
startService()
方法啟動的服務(wù)且不屬于上述兩個更高類別進(jìn)程的進(jìn)程冀偶。盡管服務(wù)進(jìn)程與用戶所見內(nèi)容沒有直接關(guān)聯(lián),但是它們通常在執(zhí)行一些用戶關(guān)心的操作(例如渔嚷,在后臺播放音樂或從網(wǎng)絡(luò)下載數(shù)據(jù))进鸠。因此,除非內(nèi)存不足以維持所有前臺進(jìn)程和可見進(jìn)程同時運(yùn)行形病,否則系統(tǒng)會讓服務(wù)進(jìn)程保持運(yùn)行狀態(tài)客年。 -
后臺進(jìn)程 (Background process)
包含目前對用戶不可見的 Activity 的進(jìn)程(已調(diào)用 Activity 的
onStop()
方法)。這些進(jìn)程對用戶體驗沒有直接影響漠吻,系統(tǒng)可能隨時終止它們量瓜,以回收內(nèi)存供前臺進(jìn)程、可見進(jìn)程或服務(wù)進(jìn)程使用途乃。 通常會有很多后臺進(jìn)程在運(yùn)行绍傲,因此它們會保存在 LRU (最近最少使用)列表中,以確保包含用戶最近查看的 Activity 的進(jìn)程最后一個被終止耍共。如果某個 Activity 正確實現(xiàn)了生命周期方法烫饼,并保存了其當(dāng)前狀態(tài),則終止其進(jìn)程不會對用戶體驗產(chǎn)生明顯影響划提,因為當(dāng)用戶導(dǎo)航回該 Activity 時枫弟,Activity 會恢復(fù)其所有可見狀態(tài)。有關(guān)保存和恢復(fù)狀態(tài)的信息鹏往,請參閱 Activity文檔淡诗。 -
空進(jìn)程 (Empty process)
不含任何活動應(yīng)用組件的進(jìn)程骇塘。保留這種進(jìn)程的的唯一目的是用作緩存,以縮短下次在其中運(yùn)行組件所需的啟動時間韩容。 為使總體系統(tǒng)資源在進(jìn)程緩存和底層內(nèi)核緩存之間保持平衡款违,系統(tǒng)往往會終止這些進(jìn)程。
關(guān)于進(jìn)程優(yōu)先級需要注意的內(nèi)容:
根據(jù)進(jìn)程中當(dāng)前活動組件的重要程度群凶,Android 會將進(jìn)程評定為它可能達(dá)到的最高級別插爹。例如,如果某進(jìn)程托管著服務(wù)和可見 Activity请梢,則會將此進(jìn)程評定為可見進(jìn)程赠尾,而不是服務(wù)進(jìn)程。
此外毅弧,一個進(jìn)程的級別可能會因其他進(jìn)程對它的依賴而有所提高气嫁,即服務(wù)于另一進(jìn)程的進(jìn)程其級別永遠(yuǎn)不會低于其所服務(wù)的進(jìn)程。 例如够坐,如果進(jìn)程 A 中的內(nèi)容提供程序為進(jìn)程 B 中的客戶端提供服務(wù)寸宵,或者如果進(jìn)程 A 中的服務(wù)綁定到進(jìn)程 B 中的組件,則進(jìn)程 A 始終被視為至少與進(jìn)程 B 同樣重要元咙。
由于運(yùn)行服務(wù)的進(jìn)程其級別高于托管后臺 Activity 的進(jìn)程梯影,因此啟動長時間運(yùn)行操作的 Activity 最好為該操作啟動服務(wù),而不是簡單地創(chuàng)建工作線程庶香,當(dāng)操作有可能比 Activity 更加持久時尤要如此甲棍。例如,正在將圖片上傳到網(wǎng)站的 Activity 應(yīng)該啟動服務(wù)來執(zhí)行上傳脉课,這樣一來救军,即使用戶退出 Activity,仍可在后臺繼續(xù)執(zhí)行上傳操作倘零。使用服務(wù)可以保證唱遭,無論 Activity 發(fā)生什么情況,該操作至少具備“服務(wù)進(jìn)程”優(yōu)先級呈驶。 同理拷泽,廣播接收器也應(yīng)使用服務(wù),而不是簡單地將耗時冗長的操作放入線程中袖瞻。