Android性能優化(五)進程保活

一、進程的優先級

Android 系統將盡量長時間地保持應用進程,但爲了新建進程或運行更重要的進程,需要清除舊進程來回收內存。 爲了確定保留或終止哪些進程,系統會對進程進行分類。 需要時,系統會首先消除重要性最低的進程,然後是清除重要性稍低一級的進程,依此類推,以回收系統資源。

https://developer.android.google.cn/guide/components/processes-and-threads.html?hl=zh-cn

 

二、Low Memory Killer

系統出於體驗和性能上的考慮,app在退到後臺時系統並不會真正的kill掉這個進程,而是將其緩存起來。打開的應用越多,後臺緩存的進程也越多。在系統內存不足的情況下,系統開始依據自身的一套進程回收機制來判斷要kill掉哪些進程,以騰出內存來供給需要的app, 這套殺進程回收內存的機制就叫 Low Memory Killer。

cat /sys/module/lowmemorykiller/parameters/minfree

這些數字的單位是page. 1 page = 4 kb

 

內存閾值在不同的手機上不一樣,一旦低於該值,Android便開始按順序關閉進程. 因此Android開始結束優先級最低的空進程,即當可用內存小於180MB(46080)

三、oom_adj

  進程的優先級通過進程的adj值來反映,它是linux內核分配給每個系統進程的一個值,進程回收機制根據這個值來決定是否進行回收。adj的值越小,進程的優先級越高。

 

可以通過cat /proc/進程id/oom_adj可以看到當前進程的adj值。(需要[root]權限)

 

 

Home鍵後:(不同的ROM可能不一樣)

adj越大,佔用內存越多會被最先kill掉,所以保活就成了降低oom_adj的值,以及如何使得我們應用佔的內存最少。

 

四、Activity提權

  監控手機鎖屏解鎖事件,在屏幕鎖屏時啓動1個像素透明的 Activity,在用戶解鎖時將 Activity 銷燬掉。從而達到提高進程優先級的作用。

缺陷:  存在一個Activity不夠乾淨。同時也需要在鎖屏後才能提權

 

 

 

按下Home後鎖屏,獲得adj爲: 

 

五、Service提權

前臺進程是優先級最高的類型。在官方指南中有介紹:

 

創建一個前臺服務用於提高app在按下home鍵之後的進程優先級

 

startForeground(ID,Notification):使Service成爲前臺Service。 前臺服務需要在通知欄顯示一條: 

 

API level < 18 :參數2 設置 new Notification(),圖標不會顯示。

API level >= 18:在需要提優先級的service A啓動一個InnerService。兩個服務都startForeground,且綁定同樣的 ID。

Stop 掉InnerService ,通知欄圖標被移除

 

Home之後查看adj值

 

六、廣播拉活

  在發生特定系統事件時,系統會發出廣播,通過在 AndroidManifest 中靜態註冊對應的廣播監聽器,即可在發生響應事件時拉活。

  但是從android 7.0開始,對廣播進行了限制,而且在8.0更加嚴格https://developer.android.google.cn/about/versions/oreo/background.html#broadcasts

  可靜態註冊廣播列表:

https://developer.android.google.cn/guide/components/broadcast-exceptions.html

 

“全家桶”拉活

  有多個app在用戶設備上安裝,只要開啓其中一個就可以將其他的app也拉活。比如手機裏裝了手Q、QQ空間、興趣部落等等,那麼打開任意一個app後,其他的app也都會被喚醒。

 

七、系統Service機制拉活

將 Service 設置爲 START_STICKY,利用系統機制在 Service 掛掉後自動拉活:

START_STICKY:

  “粘性”。如果service進程被kill掉,保留service的狀態爲開始狀態,但不保留遞送的intent對象。隨後系統會嘗試重新創建service,由於服務狀態爲開始狀態,所以創建服務後一定會調用onStartCommand(Intent,int,int)方法。如果在此期間沒有任何啓動命令被傳遞到service,那麼參數Intent將爲null。

 

START_NOT_STICKY:

  “非粘性的”。使用這個返回值時,如果在執行完onStartCommand後,服務被異常kill掉,系統不會自動重啓該服務。

 

START_REDELIVER_INTENT:

  重傳Intent。使用這個返回值時,如果在執行完onStartCommand後,服務被異常kill掉,系統會自動重啓該服務,並將Intent的值傳入。

 

START_STICKY_COMPATIBILITY:

  START_STICKY的兼容版本,但不保證服務被kill後一定能重啓。

 

只要 targetSdkVersion 不小於5,就默認是 START_STICKY。

但是某些ROM 系統不會拉活。並且經過測試,Service 第一次被異常殺死後很快被重啓,第二次會比第一次慢,第三次又會比前一次慢,一旦在短時間內 Service 被殺死4-5次,則系統不再拉起。

 

八、賬戶同步 拉活  

  手機系統設置裏會有“帳戶”一項功能,任何第三方APP都可以通過此功能將數據在一定時間內同步到服務器中去。系統在將APP帳戶同步時,會將未啓動的APP進程拉活。

  https://github.com/googlesamples/android-BasicSyncAdapter

在AuthenticationService的onBind需要返回AbstractAccountAuthenticator的getIBinder

 

 

8.1 添加帳戶

 

 

 

8.2 同步帳戶 

 

同樣需要創建一個Service作爲同步Service,並且在onBind返回AbstractThreadedSyncAdapter的getSyncAdapterBinder

 

 

8.3 開啓同步 

爲了達到進程保活的效果,可以開啓自動同步。

時間間隔雖然設置了5s,但是Android本身爲了考慮同步所帶來的消耗和減少喚醒設備的次數,5s只是一個參考時間

 

 

九、JobScheduler 拉活

  JobScheduler允許在特定狀態與特定時間間隔週期執行任務。可以利用它的這個特點完成保活的功能,效果即開啓一個定時器,與普通定時器不同的是其調度由系統完成。

  同樣在某些ROM可能並不能達到需要的效果(某米)  

十、可以使用將應用加入白名單的方法

具體詳見:

https://mp.weixin.qq.com/s/UDbXsjHixvFnt1aRLWzVzg

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章