凡是做過幾年Android開發的,都不能不面對進程保活這一問題。特別是這兩年,面對谷歌,國內定制ROM,安全軟件等多方圍剿的情況下,app在后臺保活的難度越來越大,可以說包括QQ、微信在內的所有app,都無法做到一直運行于后臺。因此,進程保活一直都是Android開發的一大難題。
Android進程保活工作包含兩部分:
1、如何盡量保持進程不被殺死
2、當進程被殺死時,如何重新啟動
如何盡量保持進程不被殺死?
如何盡量保持進程不被殺死?這個就必須說到進程優先級?(具體可自行百度),我們需要了解的進程優先級主要有五個:前臺進程,可見進程,服務進程,后臺進程(緩存進程),空進程。顯而易見,不希望進程被殺死,就需要保持其有一個高的優先級。
因此,幫助進程獲取高優先級是一種保活方式,具體實現包括:
1、app進入后臺時綁定一個透明的Activity(建議在鎖屏時開啟activity,解鎖后結束activity,針對Android鎖屏5s后自動結束后臺進程的設定)
2、后臺服務設置startForeground/setForeground(此時需要在系統的通知欄發送一條通知)。
3、application設置persistent屬性,即標注為常駐進程
另外,進程為什么會被殺死?這個主要分三種情況:用戶主動終止進程,后臺進程管理軟件殺掉進程,系統資源不夠自動干掉進程(與進程優先級及資源占用有關)。前兩者我們不可控,但第三中情況可以進行優化。前面說到了進程優先級,那現在就說說內存占用。理論上,如果內存足夠大,那空進程以外的進程都不會有被自動殺死的風險,而實際上,內存是有限的,那我們能做的就只有減少內存占用(同一進程優先級,系統也會根據進入后臺的時間長短、內存占用大小等去殺死進程)。
1、app內存優化,這個是一款合格app必須做到,不多說
2、減少服務/后臺進程的內存占用(比如讓服務運行在非進程中,在AndroidManifest.xml中配置android:process)
如何進行進程拉活?
前面提高進程優先級,減少內存占用等,都只是盡可能的降低進程被kill的手段,進程被殺死時不可避免的。那么,當進程被殺死時,我們就需要考慮如何將其重新開啟,即進程拉活,這是進程保活的關鍵。
這個相信做Android的都會一些:
1、監聽系統靜態廣播(受系統限制,可能不同版本某些廣播接收不到)
2、service的onStartCommand方法里返回 STATR_STICK,onDestory中start自啟(準確的將算不上進程拉活,只能算service自啟,force_stop后不能正常拉活)
3、監聽第三方app開放的靜態廣播(需要大量反編譯app去找開放的靜態廣播,而且不保證長期有效,可能第三方開放廣播在版本升級時改為私有廣播,如果自己公司有多個app,可廣播互相拉起)
4、利用AlarmManager定時喚起(killBackgroundProcess可以喚起但force-stop后無法喚起)
5、守護進程(一般采用Native進程,5.0以下拉活沒問題,5.0以上由于改為殺死進程的同時干掉了進程組,所以父子型守護進程將無法保證重啟)
6、雙Native獨立進程,互相守護(對5、守護進程的補充,非父子關系,這種方式在github上看到過開源項目MarsDaemon?,但僅兼容到Android6.0)
7、利用賬戶同步,定時喚醒(用到ContentProvider及SyncAdapter,①需要用戶手動設置賬戶,②因為賬戶同步是定時的,喚起周期長,不能即使喚起,③在Android N以下系統一般都能正常喚起,Android N失效)
8、使用JobSheduler機制保活(Android5.x、6.x有效,但AndroidN失效,Android N可以了解下scheduleAsPackage)
9、notificationListenerService(Android4.3+)(需要用戶授權,通過用戶授權來獲取到特定權限達到保活的目的,Android4.3以下參考AccessibilityService)
ps:隨著Android版本的不斷更新及國內廠商對ROM的不斷優化,如何最大可能的對進程保活,是Android一道需要長期學習/鉆研的學問,也是Android開發者不得不面對的問題。這里只是提到一些保活的手段,具體如何實現,基本根據上述關鍵字百度都可以搜到。后續有時間可能會另寫幾篇相關實現方法的文章。
轉自我的簡書