文章目錄
爲什麼要保活,什麼是LMKD
Google 官方解釋如下:
Android Low Memory Killer Daemon (lmkd) is a process monitoring memory
state of a running Android system and reacting to high memory pressure
by killing the least essential process(es) to keep system performing
at acceptable levels.
此處引用連接
LMKD是一個進程,它監視正在運行的Android系統的內存狀態,並通過殺死最不重要的進程(es)
來應對高內存壓力,從而使系統的性能保持在可接受的水平。所有應用進程都是從zygote孵化出來的,
記錄在AMS中mLruProcesses列表中,由AMS進行統一管理,
AMS中會根據進程的狀態更新進程對應的oom_adj值,這個值會通過文件傳遞到kernel中去,
kernel有個低內存回收機制,在內存達到一定閥值時會觸發清理oom_adj值高的進程騰出更多的內存空間
進程優先級可以參考ProcessList.java @6.0.1_r63,
不同*_ADJ的有不同優先級,值越大優先級越低,
ProcessList.java @7.1.2_r38以後版本的值,稍微有些變化
adb shell
su
//查看minfree的值,安卓10以後沒有目錄/sys/module/lowmemorykiller/,待進一步分析
cat /sys/module/lowmemorykiller/parameters/minfree
//查看adj的值
cat /sys/module/lowmemorykiller/parameters/adj
//查看進程<pid>的adj值
cat /proc/<pid>/oom_adj
cat /proc/<pid>/oom_score_adj
Lmkd.c 解析可以參考lowmemorykiller總結
本文連接 https://blog.csdn.net/CSqingchen/article/details/105362755
Service保活方案
1. Activity提權
原理:監控手機鎖屏解鎖事件,在屏幕鎖屏時啓動1個像素透明的 Activity,
在用戶解鎖時將 Activity 銷燬掉,從而達到提高進程優先級的作用。
示例代碼: Gitee: ServiceDaemon
2. Service機制(Sticky)拉活
-
將 Service 設置爲 START_STICKY,利用系統機制在 Service 掛掉後自動拉活.
-
如果service進程被kill掉,保留service的狀態爲開始狀態,但不保留遞送的intent對象。
隨後系統會嘗試重新創建service,由於服務狀態爲開始狀態,
所以創建服務後一定會調用onStartCommand(Intent,int,int)方法。
如果在此期間沒有任何啓動命令被傳遞到service,那麼參數Intent將爲null。 -
只要 targetSdkVersion 不小於5,就默認是 START_STICKY。
但是某些ROM 系統不會拉活。並且經過測試,Service 第一次被異常殺死後很快被重啓,
第二次會比第一次慢,第三次又會比前一次慢,
一旦在短時間內 Service 被殺死4-5次,則系統不再拉起。
3. Native拉活
詳細可以參考
博文 Android 進程常駐(3)----native保活5.0以下方案推演過程以及代碼詳述
源碼 Github:MarsDaemon
4. “全家桶”拉活
有多個app在用戶設備上安裝,只要開啓其中一個就可以將其他的app也拉活。
比如手機裏裝了百度、百度網盤、百度錢包等等,那麼打開任意一個app後,其他的app也都會被喚醒。
然而我們小廠的應用很難做到一個用戶手機裏面安裝我們的多常用個應用
5. 廣播拉活
在發生特定系統事件時,系統會發出廣播,通過在 AndroidManifest 中靜態註冊對應的廣播監聽器,
即可在發生響應事件時拉活。但是從android 7.0開始,對廣播進行了限制,而且在8.0更加嚴格
目前可以註冊靜態廣播有:
ACTION_LOCKED_BOOT_COMPLETED、ACTION_BOOT_COMPLETED、
ACTION_USB_ACCESSORY_ATTACHED、ACTION_USB_ACCESSORY_DETACHED、
ACTION_USB_DEVICE_ATTACHED、ACTION_USB_DEVICE_DETACHED、
ACTION_CONNECTION_STATE_CHANGED、ACTION_CONNECTION_STATE_CHANGED、
ACTION_ACL_CONNECTED、ACTION_ACL_DISCONNECTED等
詳細參見 Google Android Broadcast-Exceptions
6. Service提權
創建一個前臺服務用於提高app在按下home鍵之後的進程優先級,
也就是使用startForeground(ID,Notification)使Service成爲前臺Service,
前臺服務需要在通知欄顯示一條通知
示例源碼:Gitee ServiceDaemon FrondServiceNotification.java
7. 推送拉活
根據終端不同,在小米手機(包括 MIUI)接入小米推送、華爲手機接入華爲推送。
小米消息推送接入文檔
華爲推送服務接入文檔
其它手機廠商可以搜索
8. JobScheduler拉活
JobScheduler允許在特定狀態與特定時間間隔週期執行任務。
可以利用它的這個特點完成保活的功能,效果即開啓一個定時器,與普通定時器不同的是其調度由系統完成。
示例源碼 Gitee: [email protected]
測試結果如下
2020-04-07 13:17:11.428 21328-21328/ E/MyJobService: 開啓job
2020-04-07 13:17:15.685 21328-21328/ E/MyJobService: 開啓job
2020-04-07 13:18:37.790 21328-21328/ E/MyJobService: 開啓job
2020-04-07 13:22:07.941 21328-21328/ E/MyJobService: 開啓job
2020-04-07 13:25:37.984 21328-21328/ E/MyJobService: 開啓job
2020-04-07 13:29:08.087 21328-21328/ E/MyJobService: 開啓job
2020-04-07 13:29:12.054 21328-21328/ E/MyJobService: 開啓job
2020-04-07 13:30:08.712 21328-21328/ E/MyJobService: 開啓job
9. 賬戶同步拉活
手機系統設置裏會有“帳戶”一項功能,
任何第三方APP都可以通過此功能將數據在一定時間內同步到服務器中去。
系統在將APP帳戶同步時,會將未啓動的APP進程拉活
示例源碼Github: BasicSyncAdapter 或者Gitee: ServiceDaemon
10. 雙進程守護
兩個進程共同運行,如果有其中一個進程被殺,
那麼另外一個進程就會將被殺的進程重新拉起
示例源碼 Gitee: ServiceDaemon
11. 手機設置白名單、自啓動等
依據不同手機,更改不同的設置即可
總結
以上方法可以提供後臺服務的存活,在實際使用中很難做到100%,
主要是因爲安卓系統對後臺服務的限制越來越嚴格
本文連接 https://blog.csdn.net/CSqingchen/article/details/105362755