Android系統(tǒng)會盡可能時間長的來維持一個程序的進(jìn)程,但當(dāng)系統(tǒng)資源緊張的時候,系統(tǒng)終究會為一些新的或者更重要的進(jìn)程殺死一些舊的進(jìn)程來釋放內(nèi)存淘捡。系統(tǒng)主要是根據(jù)進(jìn)程中組件的運行狀態(tài),來決定每一個進(jìn)程的重要性,從而決定哪個進(jìn)程需要殺死,哪個進(jìn)程需要保持羊瘩。最不重要的進(jìn)程最容易先被殺死,其次最不重要的進(jìn)程會被殺死,以此往復(fù),直到系統(tǒng)恢復(fù)了需要的資源怒医。
既然系統(tǒng)主要根據(jù)進(jìn)程的重要性來決定一個進(jìn)程的存亡,下面我們就將介紹根據(jù)重要性分類的五種不同進(jìn)程(重要性由高到低)昧碉。
1.foreground process,前臺進(jìn)程
所謂前臺進(jìn)程就是指用戶完成當(dāng)前工作而需要的進(jìn)程旗芬。判斷條件如下(滿足其一即可):
- 進(jìn)程中的某個Activity正在與用戶進(jìn)行交互(Activity的onResume()方法被調(diào)用)
- 綁定到與當(dāng)前用戶正在交互的activity的Service所在的進(jìn)程
- 進(jìn)程中的某個Service正運行在前臺,即這個service的startForeground()方法被調(diào)用
- 進(jìn)程中的某個Service正在執(zhí)行生命周期回調(diào)方法(比如,onCreate(),onStart(),或者onDeatroy())
- 進(jìn)程中的BroadcastReceiver正在執(zhí)行onReceive()方法踱启。
一般來說的話,在某特定時刻,也僅會有為數(shù)不多的幾個前臺進(jìn)程俏讹。這些前臺進(jìn)程的重要性最高,當(dāng)系統(tǒng)內(nèi)存低到很低,以致不能繼續(xù)運行這些所有的進(jìn)程的話,系統(tǒng)將會殺死這些進(jìn)程弯菊。這種情況下,一般是指系統(tǒng)已經(jīng)到了一個極限邊緣了,所以為了讓UI繼續(xù)有反應(yīng)的話,系統(tǒng)不得不殺死一些前臺進(jìn)程纵势。
2.可視進(jìn)程-visible process
可視進(jìn)程是指沒有前臺運行的組件,但仍然會對用戶在屏幕看到的內(nèi)容造成影響的進(jìn)程。滿足下面條件的進(jìn)程都可以算作可視進(jìn)程:
- 進(jìn)程運行的Activity不在前臺,但仍然是可見的(調(diào)用了onPause()方法)管钳。這種情況可能是這樣的,正在前臺運行的Activity啟動了一個對話框,這個對話框懸浮在這個activity之上,但仍有部分可見钦铁。
- 進(jìn)程中的Service綁定到了一個可視(或前臺)的activity(該activity已調(diào)用了onPause()方法)。
可視進(jìn)程也是有著極高重要性的進(jìn)程,只有在系統(tǒng)為了保持前臺進(jìn)程運行而不得不殺死可視進(jìn)程的時候,才會殺死可視進(jìn)程才漆。
3.服務(wù)進(jìn)程-service process
所謂的服務(wù)進(jìn)程,就是指除了上面兩種進(jìn)程外,如果一個進(jìn)程已經(jīng)通過startService()方法啟動了一個service的進(jìn)程牛曹。雖然這種service進(jìn)程跟用戶的看到的內(nèi)容不相關(guān),但它們所做的工作也是用戶關(guān)心的(比如在后臺播放音樂或者正在下載互聯(lián)網(wǎng)上的資源),系統(tǒng)會一直保持服務(wù)進(jìn)程,除非系統(tǒng)為了前臺進(jìn)程和可視進(jìn)程的運行,而不得不殺死服務(wù)進(jìn)程。
4.后臺進(jìn)程-background process
后臺進(jìn)程是指進(jìn)程中的activity當(dāng)前對用戶來說不可見(這個activity調(diào)用了onStop()方法)栽烂。后臺進(jìn)程不會對用戶的體驗造成任何影響,并且系統(tǒng)可以在前臺進(jìn)程躏仇、可視進(jìn)程恋脚、服務(wù)繼承需要內(nèi)存資源的時候會殺死后臺進(jìn)程。通常會有很多后臺進(jìn)程運行,并且這些后臺進(jìn)程保存在一個最近使用列表中,這樣做的好處就是保證用戶最近看到的進(jìn)程最后被殺死焰手。如果一個activity已經(jīng)正確的實現(xiàn)了生命周期方法,并且保存了當(dāng)前的狀態(tài),那么系統(tǒng)殺死這些后臺進(jìn)程對用戶的可視效果來說的話,沒有任何影響,因為當(dāng)用戶返回回來的時候,這個activity已經(jīng)保存了所有的可視狀態(tài)糟描。
5.空進(jìn)程-empty process
一個空進(jìn)程沒有任何運行的程序組件。系統(tǒng)保持空進(jìn)程存在的唯一原因就是為了緩存方面的考慮,這樣做主要是為了提高組件的啟動時間书妻。系統(tǒng)經(jīng)常會殺死這些空進(jìn)程來保持整個系統(tǒng)資源和內(nèi)核緩存之間的平衡船响。
Android根據(jù)進(jìn)程中運行的最重要的組件進(jìn)行劃分進(jìn)程的重要性,比如說,如果一個進(jìn)程中即有一個可視的activity,又有一個service,那么這個進(jìn)程應(yīng)該屬于可視進(jìn)程而不是服務(wù)進(jìn)程。
另外,一個進(jìn)程的重要性等級可能會因為依賴于該進(jìn)程的其他進(jìn)程而提高——一個服務(wù)于其他進(jìn)程的重要性不會低于被服務(wù)的進(jìn)程躲履。比如說,進(jìn)程A中的一個content provider正在為進(jìn)程B中的客戶服務(wù),或者進(jìn)程A中的一個service被綁定到了進(jìn)程B中的一個組件,那么進(jìn)程A的重要性至少會被認(rèn)為是和B的重要性是一樣的见间。
因為一個正在運行的服務(wù)所在的進(jìn)程的重要性高于一個處于后臺的activity所在的進(jìn)程,所以根據(jù)這一點,如果一個activity如果要執(zhí)行需要長時間運行的操作的話,這個activity最好為該操作啟動一個新的服務(wù),而不是僅僅創(chuàng)建一個工作線程,尤其是當(dāng)這個工作線程運行的時間可能比該activity的運行時間還長的時候。比如說,如果一個activity要往一個網(wǎng)站上上傳一張圖片的話,這個activity就應(yīng)該啟動一個服務(wù)來完成這個上傳操作,這要做的好處就是即使用戶離開了當(dāng)前的這個activity,上傳服務(wù)還會繼續(xù)進(jìn)行工猜。使用一個服務(wù)保證一個進(jìn)程至少還有服務(wù)進(jìn)程這個優(yōu)先級,而不用擔(dān)心activity會發(fā)生什么情況米诉。這也正是為什么廣播接收者應(yīng)該使用服務(wù)而不是把耗時的操作放在一個線程中的原因。