Android 中進(jìn)程的級(jí)別以及 Service 的優(yōu)先級(jí)
由于在 bindService 啟動(dòng) service 的時(shí)候需要傳入 flag (可以看一下這篇文章)Service 瓤的,這里有介紹 flag 的作用遥椿,和啟動(dòng)的 Service 的優(yōu)先級(jí)有關(guān)系蜜暑,一般傳入:BIND_AOUT_CREATE
络拌,這里我們需要了解一下 Android 中進(jìn)程的優(yōu)先級(jí)的情況。
進(jìn)程的五個(gè)常用級(jí)別:
-
前臺(tái)進(jìn)程(Foreground process):前臺(tái)進(jìn)程就是用戶當(dāng)前要處理的所有事情都必須要使用的進(jìn)程监嗜。滿足下面的各種情況則認(rèn)為是前臺(tái)進(jìn)程吊输。
- 進(jìn)程持有一個(gè)正在和用戶交互的 Activity声畏。
- 進(jìn)程持有一個(gè) Service啄栓,這個(gè) Service 處于這幾種狀態(tài):1. Service 與用戶正在交互的 Activity 綁定娄帖。 2. Service 是在前臺(tái)運(yùn)行的。 3. Service 正在執(zhí)行它的生命周期 onCreate() onStrarCommand昙楚,onDestroy近速。 4. 進(jìn)程持有一個(gè) BroadcastReceiver 這個(gè) BroadcastReceiver 正在執(zhí)行它的 onReceiver 方法。
殺死前臺(tái)進(jìn)程需要用戶交互堪旧,前臺(tái)進(jìn)程的優(yōu)先級(jí)最高
-
可見(jiàn)進(jìn)程(Visible process):如果一個(gè)進(jìn)程不含任何前臺(tái)的組件削葱,但仍可被用戶在屏幕上看到。當(dāng)滿足下面任意一條的時(shí)候淳梦,進(jìn)程被認(rèn)為是可見(jiàn)的析砸。
- 進(jìn)程持有一個(gè) activity,這個(gè) activity 不在前臺(tái)爆袍。但是仍然可見(jiàn)的情況首繁。
- 進(jìn)程持有一個(gè) Service 作郭,這個(gè) Service 與一個(gè)可見(jiàn)的 Activity 綁定。
可見(jiàn)的進(jìn)程也被認(rèn)為很重要蛮瞄,一般不會(huì)被銷毀所坯,除非是為了保證所有前臺(tái)進(jìn)程的運(yùn)行而不得已不殺死可見(jiàn)進(jìn)程的時(shí)候
服務(wù)進(jìn)程(Service process):如果一個(gè)進(jìn)程中運(yùn)行著一個(gè) Service谆扎,這個(gè) Service 是通過(guò) startService() 開(kāi)啟的挂捅,并且不屬于上面兩種較高優(yōu)先級(jí)的情況下,這個(gè)進(jìn)程就是一個(gè)服務(wù)進(jìn)程堂湖。盡管服務(wù)進(jìn)程沒(méi)有和用戶可以看到的東西綁定闲先,但是它們一般在做的事情是用戶關(guān)心的,比如后臺(tái)播放音樂(lè)无蜂,后臺(tái)下載數(shù)據(jù)等伺糠。所以系統(tǒng)會(huì)盡量維持它們的運(yùn)行,除非系統(tǒng)內(nèi)存不足以維持前臺(tái)進(jìn)程和可見(jiàn)進(jìn)程的運(yùn)行需要(這句話和沒(méi)說(shuō)一樣)
-
后臺(tái)進(jìn)程(Background process):如果進(jìn)程不屬于上面三種情況斥季,但是進(jìn)程持有一個(gè)用戶不可見(jiàn)的 activity (activity 的 onStop 被調(diào)用训桶,但是 onDestroy 沒(méi)有被調(diào)用的狀態(tài))就認(rèn)為進(jìn)程是一個(gè)后臺(tái)進(jìn)程。
后臺(tái)進(jìn)程不直接影響用戶體驗(yàn)酣倾,系統(tǒng)會(huì)為了前臺(tái)進(jìn)程舵揭、可見(jiàn)進(jìn)程、服務(wù)進(jìn)程而任意殺死后臺(tái)進(jìn)程躁锡,通常情況下會(huì)有很多后臺(tái)進(jìn)程存在午绳,他們會(huì)被保存在一個(gè) LRU(least recently used)列表中,這樣就可以確保用戶最近使用的 Activity 最后被銷毀映之,先銷毀時(shí)間最遠(yuǎn)的 Activity拦焚。
空進(jìn)程:如果一個(gè)進(jìn)程不包含任何活躍的應(yīng)用組件,則認(rèn)為是空進(jìn)程杠输。例如:一個(gè)進(jìn)程當(dāng)中已經(jīng)沒(méi)有數(shù)據(jù)運(yùn)行了赎败,但是內(nèi)存當(dāng)中還為這個(gè)應(yīng)用保留了一個(gè)進(jìn)程空間。保存這種進(jìn)程的唯一理由是為了緩存的需要蠢甲,為了加快下次啟動(dòng)這個(gè)進(jìn)程中組件的啟動(dòng)時(shí)間螟够,這種空進(jìn)程經(jīng)常被殺死。
總結(jié): 我們已經(jīng)知道有這 5 個(gè)進(jìn)程了峡钓,并且他們的優(yōu)先級(jí)都列出來(lái)的妓笙,這樣我們就可以根據(jù)優(yōu)先級(jí)來(lái)讓我們的 APP 盡量不被殺死了。
下面再來(lái)說(shuō)一下 BindService() 方法中的 flag 參數(shù):
-
BIND_AUOT_CREATE:
只要綁定存在就會(huì)自動(dòng)創(chuàng)建這個(gè) Service能岩,雖然創(chuàng)建了 Service寞宫,但是它的 onStartCommand 方法是不會(huì)調(diào)用的,因?yàn)檫@個(gè)方法只有在 startService 的時(shí)候被調(diào)用拉鹃。
在 Android 4.0 以前辈赋,不提供這個(gè)標(biāo)志的話鲫忍,會(huì)影響系統(tǒng)判定當(dāng)前 Service 進(jìn)程的重要性(會(huì)把它認(rèn)為是后臺(tái)進(jìn)程),當(dāng)要設(shè)置的時(shí)候钥屈,告訴系統(tǒng)進(jìn)程重要性的唯一方式是悟民,通過(guò) bindService 來(lái)實(shí)現(xiàn),在這種情況下篷就,只有 Activity 在前臺(tái)才會(huì)起作用射亏。(這樣 Service 進(jìn)程的優(yōu)先級(jí)等同于啟動(dòng)它的進(jìn)程的優(yōu)先級(jí))。
現(xiàn)在要想把 Service 進(jìn)程的優(yōu)先級(jí)降低竭业,必須提供新的 falg (BIND_ADJUST_WITH_ACTIVITY)智润。考慮到兼容性未辆,如果沒(méi)有指定 BIND_AUTO_CREATE 的時(shí)候窟绷,系統(tǒng)會(huì)自動(dòng)加上 BIND_WAIVE_PRIORITY 和 BIND_ADJUST_WITH_ACTIVITY 來(lái)實(shí)現(xiàn)降低優(yōu)先級(jí)的效果。因?yàn)樵?Android 4.0 以前 Service 的優(yōu)先級(jí)默認(rèn)是后臺(tái)進(jìn)程咐柜,在 Android 4.0 之后默認(rèn)是等同于宿主進(jìn)程兼蜈,所以只有設(shè)置了 BIND_WAIVE_PRIORITY 后才會(huì) 4.0 和 4.0以前都兼容起來(lái)被當(dāng)做后臺(tái)任務(wù)對(duì)待。
-
BIND_DEBUG_UNBIND:
用來(lái) debug 使用的
-
BIND_NOT_FOREGROUND
不允許將綁定的 Service 的進(jìn)程提升到前臺(tái)進(jìn)程的優(yōu)先級(jí)拙友,它將仍然擁有和客戶端同樣的內(nèi)存優(yōu)先級(jí)为狸,所以在宿主進(jìn)程沒(méi)有被殺死的情況下,Service 的進(jìn)程也是不會(huì)被殺死的献宫。但是 cpu 可能會(huì)把它放在后臺(tái)執(zhí)行钥平。僅僅在這種情況下會(huì)有作用,宿主進(jìn)程在前端姊途,Service 進(jìn)程在后臺(tái)
-
BIND_ABOVE_CLIENT
在這種情況下涉瘾,Service 進(jìn)程比 App 本身的進(jìn)程還有重要,當(dāng)設(shè)置后捷兰,內(nèi)存溢出的時(shí)候立叛,將會(huì)在關(guān)閉 Service 進(jìn)程前關(guān)閉 App 進(jìn)程。但是這種情況不能保證贡茅。
-
BIND_ALLOW_OOM_MANAGEMENT
允許內(nèi)存管理系統(tǒng)管理 Service 的進(jìn)程秘蛇,允許系統(tǒng)在內(nèi)存不足的時(shí)候刪除這個(gè)進(jìn)程。
-
BIND_WAIVE_PRIORITY
不影響 Service 進(jìn)程的優(yōu)先級(jí)的情況下顶考,允許 Service 進(jìn)程被加入后臺(tái)隊(duì)列中赁还。
-
BIND_IMPORITANT
這個(gè)服務(wù)對(duì)于這個(gè)客戶端來(lái)說(shuō)是非常重要的,所以應(yīng)該提升到前臺(tái)進(jìn)程的級(jí)別驹沿。一般這個(gè)進(jìn)程
會(huì)提升到可見(jiàn)的級(jí)別艘策,甚至客戶端在后臺(tái)的時(shí)候。 -
BIND_ADJUST_WITH_ACTIVITY
如果從一個(gè) Activity 綁定渊季,則這個(gè) Service 進(jìn)程的優(yōu)先級(jí)和 Activity 是否對(duì)用戶可見(jiàn)有關(guān)朋蔫。
好了罚渐,就介紹到這里,由于個(gè)人水平有限驯妄,有錯(cuò)誤的地方荷并,請(qǐng)各位不吝賜教!
由于個(gè)人精力有限青扔,多個(gè)渠道發(fā)布源织,排版可能會(huì)有問(wèn)題。重點(diǎn)維護(hù) Android開(kāi)發(fā)家園