Android 保活措施

這個文章只是Android歷史保活方案總結,沒有什麼特別的參考意義,Android 已經到10了,100%保活自己就已經不復存在,文章中全部的方案,都是有可能有用,畢竟4.4還有人用,至於要不用能夠本身參考,畢竟當PM就是讓你應用不死,你能不寫代碼嗎?優化

保活一般分爲2種方案,一種爲提升進程優先級,防止被殺,另外一種爲進程被殺死拉活.net

1. 進程優先級

Android系統會盡量的保持應用進程,可是當須要創建新的進程或者運行更重要的進程,便會回收優先級低一些的進程,這個就是lowmemorykiller的工做。而進程的優先級其實就是 /proc/pid/oom_adjrest

進程的優先級排序code

  1. 前臺進程(Foreground Process)
  2. 可見進程(Visible Process)
  3. 服務進程(Service Process)
  4. 後臺進程(Background Process)
  5. 空進程(Empty Process)

前臺進程cdn

  1. 擁有 用戶正在交互的 Activity(正處於 onResume中)
  2. 擁有 Service綁定到正處於 onResume的 Activity
  3. 擁有 Service 調用 startForeground 成爲前臺服務
  4. 擁有 Service 正在執行生命週期回調(onCreate、onStart、onDestroy)
  5. 擁有 BroadcastReceiver 正在執行 onReceive

可見進程blog

  1. 擁有 Activity 處於 onPause ,此時可見可是不可操做
  2. 擁有 Service 綁定到正處於 onPause的 Activity

服務進程排序

  1. 僅經過 startService 啓動的 Service

後臺進程生命週期

  1. 擁有 Activity 處於 onStop

空進程進程

  1. 不擁有任何活動的組件進程

2. 回收策略

從Zygote fork出來的進程都會被儲存在 ActivityManagerService.mLruProcesses 列表中,由ActivityManagerService進行統一管理。ActivityManagerService會根據進程狀態去更新進程所對應的 oom_adj 的值,當內存達到必定的閾值會觸發清理 oom_adj 高的進程。事件

參考博客

3. 保活方案

3.1 提升進程優先級

3.1.1 利用Activity

1像素Activy,監控手機解鎖屏事件,解鎖時將Activity銷燬,鎖屏時啓動,而且要無感知,在RecentTask裏移除

3.1.2 前臺服務+Notification

Service 經過 startForegroundService 啓動 ,低版本時能夠經過特殊方式對 Notification 進行隱藏,高版本沒法規避,此方案爲經過需求正向解決

3.1.3 引導用戶打開電池管理,容許應用後臺運行

目前市面上的手機,或多或少都有對進程管理有優化,可能會有容許應用後臺容許的功能,可是每款手機的入口均不相同,並且相同廠商的不一樣版本也會不一樣

具體作法,找到手機的電池管理或者系統的後臺管理,針對不一樣的手機作文字書面的提醒,提醒用戶開啓此功能,暴力一點能夠想辦法拿到此Activity的具體類名 包名等信息,進行反射調用。

此方案通常應用不要使用,工做量巨大,並且僅僅針對提醒類應用使用,好比吃藥提醒,起牀鬧鐘,這些對保活要求很是高的應用才適合

3.2 進程死後拉活

3.2.1 監聽系統靜態廣播

低版本時,靜態廣播能夠喚醒應用進程,因此監聽系統廣播,例如開機,鎖屏,解鎖等能夠作到,可是高版本不能經過靜態廣播監聽系統廣播了

3.2.2 監聽三方靜態廣播

與上個方案相似,都是運用靜態廣播能夠拉活應用爲基礎,只是發送方不是系統,並且三方應用。因此此方案可行,可是很不穩定,海外和國內用戶羣體不一樣,手機使用的APK也會不一樣,並且須要大量反編譯三方應用,投成本也很高

3.2.3 利用系統Service機制拉活

Service 的 onStartCommand 返回值,當返回值爲 START_STICKYSTART_REDELIVER_INTENT 時,服務會自動重啓,可是 Service 在短期內被殺死5次,則再也不拉起

3.2.4 利用 JobScheduler

JobScheduler 爲Android 5.0以後引入的,本質是系統定時任務,若是進程被殺,任務仍然會被執行,在7.0後 JobScheduler 添加了限制,最低間隔爲15分鐘。可是仍是有機率出現存在進程死亡後,不觸發的狀況。

3.2.5 利用 AlarmManager

本質上也是經過設置定時任務,若是進程被殺,任務也仍然會被執行,此時就能夠拉活進程。Doze模式會影響 AlarmManager 不被觸發,此時要用setAlarmClock來設置。一樣有機率出現存在進程死亡後,不觸發的狀況。

並且Android 9.0的谷歌原生手機,多了一個功能,就是顯示手機下一個的鬧鐘時間是幾點,若是用到了這種保活方式,用戶也注意到了這個功能,那麼鬧鐘上的時間會暴露有應用在明目張膽的保活

3.2.6 利用帳號同步機制

Android 系統的帳號同步機制會按期同步帳號進行,該方案目的在於利用同步機制進行進程的拉活。添加帳號和設置同步週期的代碼便可,谷歌商店會查這種保活方案,後果不知,建議慎用

代碼參考連接

3.2.7 利用Native進程拉活

利用 Linux 中的 fork 機制建立 Native 進程,在 Native 進程中監控主進程的存活,當主進程掛掉後,在 Native 進程中當即對主進程進行拉活。

感知主進程死亡:在主進程中建立一個監控文件,而且在主進程中持有文件鎖。在拉活進程啓動後申請文件鎖將會被堵塞,一旦能夠成功獲取到鎖,說明主進程掛掉,便可進行拉活。

拉活主進程:經過 Native 進程拉活主進程的部分代碼以下,即經過 am 命令進行拉活。經過指定「–include-stopped-packages」參數來拉活主進程處於 forestop 狀態的狀況。

可是 Android5.0 以上手機 會依次殺死全部進程,也會將 Native 進程殺死

3.2.8 利用雙進程拉活

啓動兩個Service A和B,處於不一樣進程,而後在A的 onStartCommand 中綁定 B,B也在A的 onStartCommand 中綁定A,經過 ServiceConnection 的回調 onServiceDisconnected ,當綁定斷開時,說明另外一個進程死亡,因而從新啓動死亡的進程(Service),6.0以後保活效果也開始有限,與Natvie進程遇到的問題類似,只有在依次殺死進程的間隔中,有概率拉活

3.3 其餘拉活方式

3.3.1 利用系統官方的服務,或者三方服務

  1. 國外可使用 Firebase 的雲端推送
  2. 國內可使用極光推送等服務

主要仍是依靠,本身應用與其餘應用使用相同SDK,而後相同的SDK裏面內置了相互喚醒功能,具體保活的效果也是依賴三方SDK的能力

相關文章
相關標籤/搜索