作者 | Anm718(酷友)
Android 系統(tǒng)長期存在應用后臺管理機制。在多數(shù)人的認知中,應用分前臺和后臺。最簡單的判別方式:顯示界面的應用就是前臺應用,在運行不顯示界面的應用就是后臺應用。
安卓十多年發(fā)展至今,應用數(shù)量龐大,實現(xiàn)的功能各不相同,那么簡單的后臺機制肯定無法滿足需求。本篇圖文詳細解釋一下 Android 的后臺管理機制。具體分三節(jié)。
目錄:
- Android 后臺機制的根本
- 內存管理:應用狀態(tài)分級、LMK 機制、與其他系統(tǒng)的區(qū)別。
- 為什么后臺應用關不掉:應用保活、自喚醒、關聯(lián)啟動。
- 斬殺惡性應用的利劍:后臺純凈、切斷喚醒、持劍人 google 的手段。
一、Android 后臺管理的根本
安卓內存管理方案:
Android 沿用了 linux 的內存管理方案,為低內存回收機制。與開多少就占用多少的 windows 不同,Android 是你不開應用,也會占用內存。在空載狀態(tài)下,Android P 占用下限約為 500mb (大概,我測試可以正常運行),上限為設備物理內存的 1/2,即開機占用一半內存。而安卓應用不存在關閉一說,退出之后仍然會留在內存中。直至剩余內存過低,才會由系統(tǒng)機制將其殺掉,回收它占用的那部分內存。
了解應用狀態(tài)的分級:
- foreground 前臺。設備當前運行的應用,你打開什么軟件,前臺應用就是什么,很容易理解吧。
- visible 可見。與前臺類似,同樣可以顯示在屏幕上,讓用戶看到,以及交互操作,如輸入法、浮窗。
- secondary 次級。后臺運行的服務,通常占用資源不大,但用戶很需要其功能,比如各家系統(tǒng)的云服務。
- hidden 后臺。后臺運行的進程,在應用運行時直接按下 home 鍵,應用仍在運行。如果應用的優(yōu)化沒做好,那么將占用大量資源。
- content_provider 內容。與用戶關系不大,通常感知不強。
- empty 空白。應用已經(jīng)停止運行,沒有進程與服務,只留下一個緩存,確保下一次打開時更迅速。
上述六種狀態(tài),越往下,重要性越低,越容易被殺掉。
Android 后臺的殺手 - Low Memory Killer:
應用在后臺運行,固然可以增加啟動速度,或便于推送信息,但內存大小和電池容量都不是無限的。當后臺一多,就會拖累性能,降低續(xù)航。系統(tǒng)自然不可能坐以待斃,等著內存爆滿死機。Android 系統(tǒng)使用了的低內存殺后臺機制 LowMemoryKiller,以下簡稱 lmk。
kernel lmk 界面
可以看到,lmk 對每個應用狀態(tài)都有對應數(shù)值。當剩余內存大小達到數(shù)值時,lmk 就會殺掉對應狀態(tài)的應用,以釋放內存。若殺掉應用,剩余內存仍然不足,便會繼續(xù)殺掉上一個狀態(tài)級別的應用,以此類推。一直殺到前臺應用,這便會造成正運行的應用或游戲閃退。當然,目前安卓機動輒 4g、8g 內存的時代,能讓 lmk 殺到前臺的應用應該不存在了吧,除非是出現(xiàn) bug。
應用在后臺占用的資源:
在固有印象中,安卓后臺應用一多,就會十分卡頓。因為應用運行是要消耗硬件資源的,不論前臺和后臺。可能在 500mb 內存的時代沒有那么明顯的感知,因為內存太小,應用留不住后臺。但從安卓機進入了 1g、2g 內存的時代,這個缺陷就一下子暴露出來了:后臺殺不死,殺死后自啟動,一個應用拖好幾條進程,一條進程又有好幾項服務,堪稱群魔亂舞。此現(xiàn)象持續(xù)了至少六年。
那這些應用消耗的是哪些資源呢?看上文的后臺分級,這些應用一般屬于次級或后臺,與前臺應用一樣運行,會占用 CPU 運算資源,數(shù)據(jù)操作會占用閃存的讀寫資源,這兩項就足以死死卡住設備,使其無法正常運行。這些資源總量是一定的,在當時性能普遍不強時,資源用一點就少一點,后臺占用大了,前臺自然要卡。
空載:
空負載
后臺開啟百度地圖:
后臺掛百度地圖
此時已經(jīng)卡到?jīng)]法正常運行了,各種動畫掉幀。
Android 與其他系統(tǒng)后臺的區(qū)別:
對于各個系統(tǒng)的應用,一般可以用兩種狀態(tài)來表示:Android 分為 “運行” 和 “停止”,IOS 分為 “前臺” 和 “凍結”,Windows 分為 “啟動” 和 “關閉”。
解釋一下:iOS 的特點是凍結式后臺,即應用留后臺但不運行,只有前臺應用能運行。這樣可以做到打開應用時秒開,但退入后臺也不消耗資源,只占用內存;Windows 特點是打開哪個應用,哪個應用就運行,點擊關閉就停止運行,并清出內存。
內存占用也是與后臺有關,舊時 Android 日常會占用 50%;iOS 內存在開機不久會爆滿,始終居于 95% 以上;而 Windows 則是應用多大,內存占用就多大,沒有應用時占用很低。
win 空載占用
還有一個 Windows Phone 系統(tǒng),是 Microsoft 基于 win 為智能手機設計的系統(tǒng),它的特點不是殺死,而是限制,對后臺應用數(shù)量限制,對每個應用占用內存限制。這種單個體小,個體總數(shù)少的限制,是非常簡單且有效的,逼開發(fā)者不得不優(yōu)化。不愧是你,微軟。
二、為什么后臺應用關不掉?
有些用戶會刻意關閉后臺,以釋放內存或增加續(xù)航,但發(fā)現(xiàn)無法關閉后臺運行的應用。這是什么原因呢?來詳細分析一下后臺管理手段與應用的關系。首先看一下后臺界面。
卡片后臺界面
在這個界面中,可以展示出你打開過的應用,并生成縮略圖。前面說過,安卓應用不存在關閉,退出后應用會進入后臺運行。這個界面,可以手動停止后臺的應用進程,就是點擊那個 × 號,或在高版本上是滑動。但此行為并不等同于強行停止!
這個界面并不是強制性停止應用,而是清理掉應用的界面,并通知應用,應該停止自己的后臺進程了。至于停止哪些服務,就是應用自己說了算。舊時安卓這個機制問題真的很大,尤其 Android K-N,和惡意應用對線簡直被爆錘。當時定制化系統(tǒng)對這些機制進行了修改,劃掉卡片即強行停止,才能對惡意應用進行反擊。
應用保活:
應用的開發(fā)者為了一些功能運行,或是一些利益原因,會對應用的后臺進程進行保護,防止被殺掉,此行為稱為應用保活。
常見的保活手段,就是留通知。在通知欄中留一條不可清除的通知,即可實現(xiàn)避免被殺。即便你在后臺界面劃掉了卡片,只要這條通知還在,那么這項服務就在,可以隨時拉起主進程,繼續(xù)運行。這樣的應用有很多,比如在通知欄里放個資訊窗口、搜索框,就是這種思路。
酷安后臺
最直接的保活手段,就是向用戶請求權限。在定制系統(tǒng)上,通常會有 “允許應用在后臺運行” 權限,應用可以找一個正當?shù)慕杩冢層脩糁鲃影堰@個權限打開,就能在后臺暢通無阻的運行了。
除此之外還有一些奇妙操作,比如建立透明懸浮窗,可以直接提高應用狀態(tài)分級,就難以被 lmk 殺掉;進程守護,一個應用建立幾個進程,有一個進程掉了,立馬由另外一個進程拉起來;還有更強的,以毫秒級速度不停嘗試拉起自己的進程,這種方法甚至可以無視強行停止(只要我啟動的夠快,強行停止就關不掉我),這已經(jīng)是破壞型行為了。
應用喚醒:
應用會通過一些方式,在用戶未手動打開的情況下自行啟動,即應用喚醒,也稱應用自啟動。此時沒有前臺界面,啟動的只是進程與服務。
Android 應用開發(fā)時,會給應用加上 BroadcastReceiver (廣播接收器,以接收系統(tǒng)的廣播),以對一些狀態(tài)作出對應的響應,比方說此設備收到電話,系統(tǒng)就會發(fā)出廣播 “來電話了”,應用 “撥號” 就會自啟動,響鈴提醒用戶接聽。存儲空間低于一定量時,系統(tǒng)會發(fā)廣播,文件管理類應用會提示用戶清理文件以釋放空間。合理使用可以使應用極大提升功能性,但不合理使用的話,就是給用戶找麻煩。
百度云自啟
借用知乎老哥的圖。可以看出百度云會接收圖中的廣播,實現(xiàn)自啟動。WiFi 更改、存儲變動時自啟動也就罷了,畢竟功能聯(lián)網(wǎng)還要依賴存儲,但收發(fā)短信、撥打電話還要啟動干什么呢?安裝卸載應用時也啟動,充電斷電也啟動,你是多么怕自己的服務拉不起來啊?
即便殺掉了后臺,沒一會又自啟了,跟沒殺一樣。
關聯(lián)啟動:
應用的廣播接收器,不止可以接收系統(tǒng)的廣播,也可以接收其它應用的廣播,從而被其他應用拉起。
此現(xiàn)象稱為關聯(lián)啟動,或鏈式啟動。關聯(lián)啟動的常見場景:在 “手機淘寶” 中購買某件商品,選擇付款方式支付寶付款,那么就可以直接拉起 “支付寶” 的應用界面,進行付款操作。
而不合理的使用場景,對于長期的安卓用戶應該都深有感知了吧,拉起其他應用的后臺服務,收集用戶數(shù)據(jù),推送廣告。
關聯(lián)喚醒
可以看到,同一家的應用之間都會自動喚醒,保持后臺活躍。這有什么用嗎?我也不知道啊。
一開始的時候就是如此,后期此現(xiàn)象愈演愈烈,一些公司推出了關聯(lián) SDK,只要你接入了此 SDK,有接入相同 SDK 的應用啟動,就會順帶拉起你的應用。鏈式啟動成為了一種交♂易:“接入我的 SDK 吧,你的應用可以享受后臺殺不掉的待遇,消息直達,數(shù)據(jù)收集無阻礙。” 于是,大量的應用開始接入這種 SDK,后臺是不掉了。
開發(fā)者笑嘻嘻,可苦了用戶,后臺殺也殺不掉,停止了還能自啟、鏈起。內存不大的機子,在那么多的應用下不停的觸發(fā) lmk 殺后臺,剛殺掉就又起來了,陷入死循環(huán),致使負載居高不下,續(xù)航也是血崩。
三、斬殺惡性應用的利劍
對于那些惡性應用,就只看著它們胡作非為、為所欲為嗎?當然不行。反擊之戰(zhàn)早已打響,垃圾應用們,接招!
斬殺 - 應用后臺進程:
后臺純凈機制后臺純凈并不是 Android 官方提出的說法,而是第三方定義的一種應用狀態(tài)。即應用退出到后臺,不留下任何無用服務 (無用指用戶用不到),全部歸進緩存 (即上文分級中的空白進程)。既不拖累系統(tǒng)性能,也能實現(xiàn)啟動時秒開。
此說法來自于綠色公約,也就是說綠色公約中的應用可以做到這一點。但幾年過去,自愿遵守的公約已成為來自 Google 強制的規(guī)定。如你當前運行的系統(tǒng)為 Android O 及以上,且應用目標 API 在 26 以上,那么該應用退出后便可以進入緩存,實現(xiàn)無損保后臺。
你可以嘗試打開應用,使用主頁鍵退出應用界面,進入系統(tǒng)設置 - 開發(fā)者選項 - 正在運行的服務,觀察是否有剛才應用的進程和服務。然后點擊右上方的顯示緩存,是否有剛才應用的緩存。如果沒有進程服務,只留下了一個百來 mb 大小的緩存進程,那么這個應用就大概符合后臺純凈了。
進程
緩存
能看出,我常用的應用均支持后臺純凈。當然萬事無絕對,比如一個音樂播放器,在播放音樂,退出之后肯定要留一條進程的,畢竟后臺還要運行的,不能說它不支持后臺純凈。
啊。。這疼訊,永遠的
還有一些奇怪的事情,就是內存顯示錯誤,有時應用占的內存會直接算進系統(tǒng)占用里面,不知是邏輯 bug 還是應用的奇妙操作,如圖:
淘寶遁入系統(tǒng)
斬殺 - 鏈式啟動:
切斷喚醒為了應對應用的自啟動和鏈式啟動,在早期的安卓定制系統(tǒng)中,提供了應用自啟動的開關,由用戶控制自啟動。
自啟限制
關閉此開關,則系統(tǒng)會屏蔽應用的廣播接收,使其無法通過廣播自啟。對于非深度定制系統(tǒng),并沒有這類限制。如果有 root 權限,可以使用工具 【My Android Tools】 ,手動管理應用的各種組件,不但可以關閉廣播接收器,也能控制應用的后臺服務。有用不到、但卻在運行的服務,可以直接停掉。
mat
如果有 xposed 框架,則可以使用 【應用管理 Xposed】 ,功能更多,效果更強,操作更簡單。
斬殺 - 后臺資源占用
后臺應用,就應該有后臺的樣子。有些應用進入后臺還不安分,不停交換數(shù)據(jù),拖慢速度,吃掉大量資源。最過分的是喚醒鎖,使設備無法休眠。那么目標已明確,就是降低它們對資源的占用。
自安卓 8 開始,系統(tǒng)對于后臺應用進行了一次整治。如果系統(tǒng)是安卓 8,且應用的目標 API 是 26 及以上,那么這個應用會自動實現(xiàn)后臺純凈。若應用 API 低于 26,則可以到 開發(fā)者選項 - 后臺檢查 中手動限制,若不需要這個應用的后臺,則關閉即可。
后臺檢查
到了安卓 9,限后臺就更狠了。智能待機上線,可根據(jù)應用使用頻率、使用時間進行自動化管理,分活躍、工作、常用、極少這幾個等級,為后臺分配不同的資源。這也是為什么用過一段時間的機子,續(xù)航比新機還長的原因,就是機器學習記錄了你的使用習慣。
如果是不規(guī)范應用,遲遲不適配新特性呢?Google 還有更絕的招式。在 Android P 上還提供了后臺限制功能,若應用的 API 較低,且在后臺有大量進程,或長時間控制喚醒鎖,系統(tǒng)將會在通知欄將應用列出,提示為:** 應用正在后臺耗電 之類的,用戶可以對其進行一鍵限制。這個限制可不是前文所說的限制分配資源,而是直接禁止應用的一切后臺,禁止應用的一切響應,退出即停止。
此限制也可由用戶手動打開,在設置 - 應用 - 查看全部應用,找到要限制的應用,高級 - 電池 - 后臺限制,點擊限制,世界都清凈了。
另一種方法: 【App Ops】 中更改應用權限,“在后臺運行” 這個權限在安卓 9 是這樣的。
嚴格限制就是上面的限制應用。API 在 26 及以上的應用默認為基礎限制,低于 26 的應用默認為不限制,用戶都可以手動更改為嚴格限制。
能看出來,越是原生系統(tǒng),干擾越少,不存在白名單,越能體現(xiàn)出開發(fā)者的優(yōu)化水平。優(yōu)化越垃圾,在原生 ROM 上越是掛不住后臺,推不出消息。比如我的機子,就從來收不到酷安的消息通知 (whml
斬殺 - 惡性應用最后的倔強:Google 的手段
從這幾次底層的大改動可以看出,Google 已經(jīng)要大力整治這些惡性應用了,可以說是無差別打擊,只要不規(guī)范,就要受波及。
后臺限制,就是你能規(guī)范起來,那你可以在后臺合理運行,不影響功能,用戶的體驗也不會受損,你好我也好。如果就是頭鐵,就想跟系統(tǒng)比劃比劃,那好,后臺直接別運行了,你一個功能都實現(xiàn)不了。
Play 商店有著強制要求,目標 API 必須在 26 以上,且很快就要成為 28。這就意味著應用想不規(guī)范都不行,API 越高,應用受約束越多。不提升 API?也行,我不會給你下架,但我會禁止你發(fā)布更新。
如果你能做到永遠不更新,那你可以這么做。如果不上架 play 商店呢?畢竟 Google 管不到第三方分發(fā)渠道。沒關系,我不能禁止你分發(fā),但我能干擾你運行。已知 API 低于 23,運行時會提示風險應用,謹慎使用。API 遠低于當前系統(tǒng),為了兼容運行,我會降低你的一些性能。
還不能搶占國際市場,完全得不償失啊!
文末的閑聊
總有人抱怨安卓生態(tài)太差,跟競爭者 iOS 相比落后太多,這樣比較就有失公允了。想想 iOS 的出身,蘋果早在上個世紀就設計了 mac 操作系統(tǒng),針對優(yōu)化十幾年,積累了大量經(jīng)驗,并有了一定的生態(tài)基礎,設計 iOS 系統(tǒng)自然十分輕松,打好 iOS 生態(tài)也沒啥壓力。
反觀 Android,一個 Linux 內核,從零開始制作系統(tǒng),且最開始還不是為智能手機設計的。這樣的一個存在,經(jīng)歷了幾年發(fā)展,體量竟是完全壓著 iOS 打,應用數(shù)量多于 iOS,市場占有量更是 iOS 的數(shù)倍。
如果這樣還不能理解,再看看 Windows,發(fā)展數(shù)十年,生態(tài)依舊稀爛。
權限管理混亂、uwp 生態(tài)半殘。這樣是不是就感覺到 Android 的強大了?
- 問:如何正確查看剩余內存
- 答:設置 - 開發(fā)者選項 - 正在運行的服務,點擊右上方的 “顯示緩存進程”,即可查看真實剩余內存。剩余內存大小一般在 lmk 的最大值再多一點。通常是幾百 mb
- 問:我就是不想讓應用留后臺,就想看到剩余內存大大的
- 答:設置 - 開發(fā)者選項 拉到底,后臺進程限制,改為不允許后臺進程。簡單概括:剩余極大,體驗極差。
- 問:現(xiàn)在手機內存到底幾 g 合適?
- 答:要我說,3g 勉強,4g 足矣,6g 有余,8g 巔峰。12g 16g?方向錯了。廠商不想著優(yōu)化好,凈想著比友商參數(shù)好看,成本壓不下來,最后用戶買旗艦機還要提高預算。
- 問:文章太長懶得看,給總結一下
- 答:殺后臺只有 lmk 機制 和 用戶手動停止。安裝應用 API 越高越好,剩余內存越少越好。至于優(yōu)化,自己爬回去看完。
有人說我寫的圖文看不懂,我盡力去修改了,可還是哪里不對勁。對于酷安幾千粉的大佬,這些應該是基礎了吧,沒講的必要。對于剛入安的小白,可能開頭就看不懂了 (我太難了
圖文寫得有些混亂,這排版做的也挺拉跨,見諒。例行要評論。
強調版權:本圖文禁止今日頭條等營銷媒體轉載。如要引用文中語句或段落,請注明原作者 Anm718