1. 程式人生 > >打造Android不死程序

打造Android不死程序

為什麼要程序保活?

應用為什麼要在後臺一直活著?他活著做什麼?

想必所有的應用都想在後臺不死,一旦應用不死,後臺就可以嚮應用推送訊息,讓使用者看到,其實大多數應用都只是為了能夠收到後臺的推送而已,這只是適用的一個小場景,但是大家都知道,應用的推送一般都是第三方或者自己做的,而不是用的谷歌本身的推送,不像蘋果,使用的是自己原生的推送,因此蘋果不擔心推送的問題,然而Android就不一樣了,中國訪問不了谷歌,所以原生推送自然也就用不了。

在國內手機廠商中,也有許多廠商做了只屬於自己的推送,比如小米,華為,他們都有自己的一套推送系統,但是這畢竟是少數,大部分都用的是第三方推送,比如個推,極光等,還有一種就是大公司自己做的一套屬於自己的推送,小公司一般都是不會自己做的,原因大家都懂的。

為什麼會有保活

國內的手機系統都是在Android基礎上定製的,也就是說,系統被人家改過了,所以,各個手機廠商對於手機的資源分配都有不同的方式和標準。

但是一般情況下都是大致一樣了,你想一下,如果一款手機中的所有應用都在後臺一直執行,並且使用者根本沒有用到,這個時候還要佔著手機的資源,那麼手機自然也就很卡了,所以手機廠商對這一塊要求還是都比較嚴格的。

一般如果一款應用一直在後臺執行著,沒有被使用者放到前臺,這個時候系統會自動的回收資源,開始一個一個的殺死程序,這個時候所有應用都難逃被殺的命運!但是我們看市場上的應用,比如微信,QQ,為什麼怎麼都不被手機殺死,其實微信這些應用可以說是系統級別的應用了,不再單單的只是一款應用,所以,微信不能死,如果你能把軟體做到系統級別的,你也可以永久不死。

保活的場景

大家都知道,手機對於資源的監控是很嚴格的,所以我們也不應該一直常駐後臺,我們只是為了完成我們在後臺的任務時儘量保證不被系統殺死就行了,下面是保活場景:

  1. 即時通訊
  2. 後天推送
  3. 後臺計步
  4. 獲取gps

國內案例

國內,這塊做的最好的就是咕咚了,你會發現,只要你使用咕咚點選了開始運動之後,他就再也死不了了,這是非常經典的案例,此時做程序保活是非常有必要的,因為使用者一旦開始運動之後,他會直接將螢幕關閉,然後聽著歌曲來跑步,那麼這個時候就有問題了,手機一般只要使用者主動的關閉螢幕之後,過一會就開始進入系統休眠狀態,也就是開始清理後臺程式了,那麼一旦你的應用被清理,當用戶再次進入程式的時候,發現跑了10公里,居然沒有資料了,軟體直接死掉了,你說他是不是會罵娘。

所以這個時候,就應該使用應用保活,保證應用不被系統殺死,而且被殺死後,能夠重啟。

咕咚的運動結束後,你會發現,他和其他的應用是一樣的,很快就會被系統殺死,也再也不會自動重啟,這是咕咚做的比較優秀的地方。

當然我也希望,我們做應用保活,只是為了使用者好,而不是為了自己,在後臺大佔手機資源。

打造不死應用

當我們需要進行應用保活時,一方面,是為了讓應用盡量不要被系統殺死,一方面是為了自己的應用被系統殺死之後,能夠自動重啟,然後繼續收集上次未收集完的資料

程序的優先順序

Android 系統將盡量長時間地保持應用程序,但為了新建程序或執行更重要的程序,最終需要清除舊程序來回收記憶體。 為了確定保留或終止哪些程序,系統會根據程序中正在執行的元件以及這些元件的狀態,將每個程序放入“重要性層次結構”中。 必要時,系統會首先消除重要性最低的程序,然後是清除重要性稍低一級的程序,依此類推,以回收系統資源。

利用 Activity 提升許可權

方案設計思想:監控手機鎖屏解鎖事件,在螢幕鎖屏時啟動1個畫素的 Activity,在使用者解鎖時將 Activity 銷燬掉。注意該 Activity 需設計成使用者無感知。

通過該方案,可以使程序的優先順序在螢幕鎖屏時間由4提升為最高優先順序1。

方案適用範圍:

  1. 適用場景:本方案主要解決第三方應用及系統管理工具在檢測到鎖屏事件後一段時間(一般為5分鐘以內)內會殺死後臺程序,已達到省電的目的問題。
  2. 適用版本:適用於所有的 Android 版本。

利用 Notification 提升許可權

方案設計思想:Android 中 Service 的優先順序為4,通過 setForeground 介面可以將後臺 Service 設定為前臺 Service,使程序的優先順序由4提升為2,從而使程序的優先順序僅僅低於使用者當前正在互動的程序,與可見程序優先順序一致,使程序被殺死的概率大大降低。

方案實現挑戰:從 Android2.3 開始呼叫 setForeground 將後臺 Service 設定為前臺 Service 時,必須在系統的通知欄傳送一條通知,也就是前臺 Service 與一條可見的通知時繫結在一起的。

通過實現一個內部 Service,在 WatchDogService 和其內部 Service 中同時傳送具有相同 ID 的 Notification,然後將內部 Service 結束掉。隨著內部 Service 的結束,Notification 將會消失,但系統優先順序依然保持為2。

方案適用範圍:適用於目前已知所有版本。

程序死後拉活

我們要做的不僅僅是程序保活,一旦應用被系統殺死後,應用也就再也起不來了,那麼資料也就不能繼續採集了,此時候我們需要在他死之後,還能自動復活,然後繼續使用

利用系統廣播拉活

方案設計思想:在發生特定系統事件時,系統會發出響應的廣播,通過在 AndroidManifest 中“靜態”註冊對應的廣播監聽器,即可在發生響應事件時拉活。

常用的用於拉活的廣播事件包括:

  1. 開機廣播
  2. 網路變化
  3. 檔案掛載
  4. 螢幕亮滅
  5. 鎖屏解鎖
  6. 應用安裝解除安裝

方案適用範圍:適用於全部 Android 平臺。但存在如下幾個缺點:

  1. 廣播接收器被管理軟體、系統軟體通過“自啟管理”等功能禁用的場景無法接收到廣播,從而無法自啟。
  2. 系統廣播事件不可控,只能保證發生事件時拉活程序,但無法保證程序掛掉後立即拉活。

這種方案,只能用做備用方案。

利用第三方應用廣播拉活

通過反編譯第三方 Top 應用,如:手機QQ、微信、支付寶、UC瀏覽器等,以及友盟、信鴿、個推等 SDK,找出它們外發的廣播,在應用中進行監聽,這樣當這些應用發出廣播時,就會將我們的應用拉活。

利用系統Service機制拉活

方案設計思想:將 Service 設定為 START-STICKY,利用系統機制在 Service 掛掉後自動拉活

如下兩種情況無法拉活:

  1. Service 第一次被異常殺死後會在5秒內重啟,第二次被殺死會在10秒內重啟,第三次會在20秒內重啟,一旦在短時間內 Service 被殺死達到5次,則系統不再拉起。
  2. 程序被取得 Root 許可權的管理工具或系統工具通過 forestop 停止掉,無法重啟。

利用 JobScheduler, AlarmManager 機制拉活

系統在 Android5.0 以上版本提供了 JobScheduler 介面,系統會定時呼叫該程序以使應用進行一些邏輯操作。

使用 JobScheduler, Android 系統能自動拉起被 Force Stop 的 Package,而 AlarmManager 無法拉起.Android 4.4 及以下版本使用 AlarmManager

使用定時 Observable : 避免 Android 定製系統 JobScheduler / AlarmManager 喚醒間隔不穩定的情況

利用賬號同步機制拉活

方案設計思想:Android 系統的賬號同步機制會定期同步賬號進行,該方案目的在於利用同步機制進行程序的拉活。

該方案需要在 AndroidManifest 中定義賬號授權與同步服務。

方案適用範圍:該方案適用於所有的 Android 版本,包括被 forestop 掉的程序也可以進行拉活。

其他拉活方案

  1. 利用系統通知管理許可權進行拉活
  2. 利用輔助功能拉活,將應用加入廠商或管理軟體白名單。

這2個方案都親自測試過,還是可以保活且可以拉活的,但是使用者感知比較強,需要使用者授權,要想讓使用者授權還是有難度的,畢竟需要你彈框引導使用者,但是你要知道,很多使用者沒有那個耐心的,所以該方案雖然可行,但是很難實現我們想要的模樣

最後說明

  1. 以上的應用保活以及應用拉活方案,都已經實現,效果還算不錯,但是有的手機沒有測試過,大家可以借鑑,希望只是學習。

  2. 在微信公眾號:AppCode裡回覆“保活”,即可拿到原始碼下載連結

  3. 掃描下面二維碼即可關注AppCode公共號