Android 后臺保活手段總結 (上篇)
由于眾所周知的限制,在國內無法使用GCM推送服務,想要自己搭建推送服務的話,有兩個繞不開的技術點,一個是TCP長連的保活,另一個就是后臺進程的保活。雖然看起來是老生常談的問題,但竟然是收到私信里問到最多的內容。于是在這里做一個目前接觸的保活手段,做一個總體的總結
常規保活方案
利用Notification提升權限
Android 中 Service 的優先級為4,通過 setForeground 接口可以將后臺 Service 設置為前臺 Service,使進程的優先級由4提升為2,從而使進程的優先級僅僅低于用戶當前正在交互的進程,與可見進程優先級一致,使進程被殺死的概率大大降低。
需要注意的是,在最新的Android 8.0系統上,setForeground變成了強制性的行為,任何后臺Service都必須調用這個方法,否則五秒鐘后系統強制ANR Crash。這里涉及到另外的一個坑是——哪怕你的Service只是做點業務邏輯后銷毀,也需要先調用這個接口,因為不同的國產ROM重新定義了“五秒鐘”(手動滑稽),你以為只需要占用1秒的業務邏輯,上線都可能分分鐘崩潰給你看。
然而調用這個API后,系統通知欄上會顯示“XXX應用在后臺運行”,無法去掉。8.1系統上已經去掉了這個很不友好的通知欄常駐顯示。
利用系統廣播拉活
在發生特定系統事件時,系統會發出響應的廣播,通過在 AndroidManifest 中“靜態”注冊對應的廣播監聽器,即可在發生響應事件時主動嘗試拉活Service。
可以用于拉活的廣播事件包括:
備注
廣播事件
開機
RECEIVE_BOOT_COMPLETED
網絡變化
ACCESS_NETWORK_STATE CHANGE_NETWORK_STATE ACCESS_WIFI_STATE CHANGE_WIFI_STATE ACCESS_FINE_LOCATION ACCESS_LOCATION_EXTRA_COMMANDS
文件掛載
MOUNT_UNMOUNT_FILESYSTEMS
屏幕狀態變化
SCREEN_ON SCREENOFF
鎖屏解鎖
RECEIVER_USER_PRESENT
應用卸載安裝
PACKAGE_REMOVED PACKAGE_ADDED
在Android 8.0系統上,這個方法已經不生效了,因為8.0系統已經去掉了這種靜態廣播注冊的形式,系統廣播必須使用動態注冊,即應用啟動后registerReceiver,在Manifest里配置廣播已經無法生效。
另外,在某些深度定制的系統上效果一般,比如華為系統上,應用進程一旦終止,無法使用系統廣播的形式重新喚起。
利用系統Service START_STICKY機制拉活
將 Service 設置為 START_STICKY,利用系統機制在 Service 掛掉后自動拉活。最基本的方式,不解釋了。
利用Native進程拉活
Native雙進程守護的方式曾經風靡一時,被當做“黑科技”,然而遺憾的是實際上效果一般,僅僅在5.0以下系統兼容較好,深度定制的系統中:魅族、華為、小米等,都效果略差。從recent中殺進程后無法重新拉起,后臺一段時間以后也會被殺掉。僅適合5.0以下版本仍然較高的APP采用這種方法。