1. 程式人生 > >Android 程序保活,Service程序常駐

Android 程序保活,Service程序常駐

關於 Android 平臺的程序保活這一塊,想必是所有 Android 開發者矚目的內容之一。你到網上搜 Android 程序保活,可以搜出各種各樣神乎其技的做法,絕大多數都是極其不靠譜。前段時間,Github還出現了一個很火的“黑科技”程序保活庫,聲稱可以做到程序永生不死。
CSDN上也出現過一篇使用C程序守護的方式,Android程序常駐:

,也能很好的解決5.0及以下的機器。
接下來本文講的內容是來至:

主要講灰色保活。
灰色保活,這種保活手段是應用範圍最廣泛。它是利用系統的漏洞來啟動一個前臺的Service程序,與普通的啟動方式區別在於,它不會在系統通知欄處出現一個Notification,看起來就如同執行著一個後臺Service程序一樣。這樣做帶來的好處就是,使用者無法察覺到你執行著一個前臺程序(因為看不到Notification),但你的程序優先順序又是高於普通後臺程序的。那麼如何利用系統的漏洞呢,大致的實現思路和程式碼如下:

思路一:API < 18,啟動前臺Service時直接傳入new Notification();
思路二:API >= 18,同時啟動兩個id相同的前臺Service,然後再將後啟動的Service做stop處理;

public class GrayService extends Service {

    private final static int GRAY_SERVICE_ID = 1001;

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if
(Build.VERSION.SDK_INT < 18) { startForeground(GRAY_SERVICE_ID, new Notification());//API < 18 ,此方法能有效隱藏Notification上的圖示 } else { Intent innerIntent = new Intent(this, GrayInnerService.class); startService(innerIntent); startForeground(GRAY_SERVICE_ID, new
Notification()); } return super.onStartCommand(intent, flags, startId); } ... ... /** * 給 API >= 18 的平臺上用的灰色保活手段 */ public static class GrayInnerService extends Service { @Override public int onStartCommand(Intent intent, int flags, int startId) { startForeground(GRAY_SERVICE_ID, new Notification()); stopForeground(true); stopSelf(); return super.onStartCommand(intent, flags, startId); } } }

這樣能讓你神不知鬼不覺的啟動著一個前臺Service。我們可以使用adb命令列程式,在然後輸入下面的shell命令這裡寫圖片描述

打印出指定包名的所有程序中的Service資訊,看下有沒有 isForeground=true 的關鍵資訊。如果通知欄沒有看到屬於app的 Notification 且又看到 isForeground=true 則說明了,此app利用了這種灰色保活的手段。當然這也只是目前一種可行的方式,哪天google封了也是有可能的。

下面就給自己做個記錄,記錄下系統的程序回收機制
熟悉Android系統的童鞋都知道,系統出於體驗和效能上的考慮,app在退到後臺時系統並不會真正的kill掉這個程序,而是將其快取起來。開啟的應用越多,後臺快取的程序也越多。在系統記憶體不足的情況下,系統開始依據自身的一套程序回收機制來判斷要kill掉哪些程序,以騰出記憶體來供給需要的app。這套殺程序回收記憶體的機制就叫 Low Memory Killer ,它是基於Linux核心的 OOM Killer(Out-Of-Memory killer)機制誕生。

瞭解完 Low Memory Killer,再科普一下oom_adj。什麼是oom_adj?它是linux核心分配給每個系統程序的一個值,代表程序的優先順序,程序回收機制就是根據這個優先順序來決定是否進行回收。對於oom_adj的作用,你只需要記住以下幾點即可:

程序的oom_adj越大,表示此程序優先順序越低,越容易被殺回收;越小,表示程序優先順序越高,越不容易被殺回收
普通app程序的oom_adj>=0,系統程序的oom_adj才可能<0
那麼我們如何檢視程序的oom_adj值呢,需要用到下面的兩個shell命令

ps | grep PackageName //獲取你指定的程序資訊
這裡寫圖片描述

關於 Android 程序保活,你所需要知道的一切

這裡是以我寫的demo程式碼為例子,紅色圈中部分別為下面三個程序的ID

UI程序:com.clock.daemon
普通後臺程序:com.clock.daemon:bg
灰色保活程序:com.clock.daemon:gray

當然,這些程序的id也可以通過AndroidStudio獲得

這裡寫圖片描述

接著我們來再來獲取三個程序的oom_adj

cat /proc/程序ID/oom_adj

這裡寫圖片描述

從上圖可以看到UI程序和灰色保活Service程序的oom_adj=0,而普通後臺程序oom_adj=15。到這裡估計你也能明白,為什麼普通的後臺程序容易被回收,而前臺程序則不容易被回收了吧。但明白這個還不夠,接著看下圖

這裡寫圖片描述

上面是我把app切換到後臺,再進行一次oom_adj的檢驗,你會發現UI程序的值從0變成了6,而灰色保活的Service程序則從0變成了1。這裡可以觀察到,app退到後臺時,其所有的程序優先順序都會降低。但是UI程序是降低最為明顯的,因為它佔用的記憶體資源最多,系統記憶體不足的時候肯定優先殺這些佔用記憶體高的程序來騰出資源。所以,為了儘量避免後臺UI程序被殺,需要儘可能的釋放一些不用的資源,尤其是圖片、音視訊之類的。

從Android官方文件中,我們也能看到優先順序從高到低列出了這些不同型別的程序:Foreground process、Visible process、Service process、Background process、Empty process。而這些程序的oom_adj分別是多少,又是如何掛鉤起來的呢?推薦大家閱讀下面這篇文章:

總結(文末有福利)
絮絮叨叨寫完了這麼多,最後來做個小小的總結。迴歸到開篇提到QQ程序不死的問題,我也曾認為存在這樣一種技術。可惜我把手機root後,殺掉QQ程序之後就再也起不來了。有些手機廠商把這些知名的app放入了自己的白名單中,保證了程序不死來提高使用者體驗(如微信、QQ、陌陌都在小米的白名單中)。如果從白名單中移除,他們終究還是和普通app一樣躲避不了被殺的命運,為了儘量避免被殺,還是老老實實去做好優化工作吧。

所以,程序保活的根本方案終究還是回到了效能優化上,程序永生不死終究是個徹頭徹尾的偽命題!

相關推薦

Android 程序Service程序常駐

關於 Android 平臺的程序保活這一塊,想必是所有 Android 開發者矚目的內容之一。你到網上搜 Android 程序保活,可以搜出各種各樣神乎其技的做法,絕大多數都是極其不靠譜。前段時間,Github還出現了一個很火的“黑科技”程序保活庫,聲稱可以做到

關於 Android 程序你所需要知道的一切

早前,我在知乎上回答了這樣一個問題:怎麼讓 Android 程式一直後臺執行,像 QQ 一樣不被殺死?。關於 Android 平臺的程序保活這一塊,想必是所有 Android 開發者矚目的內容之一。你到網上搜 Android 程序保活,可以搜出各種各樣神乎其技的做法,絕大多數都是極其不靠譜。前段時間,Gith

android程序實踐(根據鴻洋大神彙總本人忘性大備份下)

前言程序保活的關鍵點有兩個,一個是程序優先順序的理解,優先順序越高存活機率越大。二是弄清楚哪些場景會導致程序會kill,然後採取下面的策略對各種場景進行優化:提高程序的優先順序在程序被kill之後能夠喚醒程序優先順序Android一般的程序優先順序劃分:1.前臺程序 (Foreground process)2

Android程序(常駐記憶體)

Android將程序分為6個等級,它們按優先順序順序由高到低依次是:  1.前臺程序( FOREGROUND_APP);  2.可視程序(VISIBLE_APP );  3. 次要服務程序(SECONDARY_SERVER );  4.後臺程序 (HIDDEN_APP);  

Android保證service不被殺掉-增強版: 程序(根據使用者需求慎用)

作者:騰訊——張興華 目前市面上的應用,貌似除了微信和手Q都會比較擔心被使用者或者系統(廠商)殺死問題。本文對 Android 程序拉活進行一個總結。 Android 程序拉活包括兩個層面: A. 提供程序優先順序,降低程序被殺死的概率 B. 在程序被殺死後,進行

Android後臺機制應用程序長存的可行性分析

什麼時候會造成STOPPED狀態: 重未啟動過的應用,原生的系統中,當應用初次啟動後就會被標識為非STOPPED狀態,而且再也沒有機會被打回原形除非重新安裝應用;但是一些定製系統,在清理應用時加入了將應用重置為STOPPED的邏輯。 與系統Service捆綁 Android系統提供給我們一系列的

android程序兩年實戰經驗(已經上線使用)

程序保活參考: https://www.jianshu.com/p/53c4d8303e19 https://github.com/08carmelo/android-keeplive 以上地址這個我是通過鴻洋的公眾號看到的,我們公司做的是VPN撥號必須要求app保持後臺執行,上面連

Android程序相關實踐

最近測試APP時接到個需求:1畫素保活 打眼一看,應該跟安卓程序有關係,索性找點詳細的資料來了解下: 系統什麼時候殺掉一個程序?為什麼殺掉這個程序?怎樣最大程度保活一個程序?詳細的講解可以參考這個連結------https://www.cnblogs.com/Doing-what-I-love/p/553

Android 程序資料

現在發現App在後臺執行越來越難了。App在華為手機後臺死的非常快,之前看網上說華為有白名單,網上也通過改包名的方式來驗證了。但是半信半疑的,直到諮詢了華為的客服給了一個郵箱 [email protected],回覆的資料 應用加白名單簡化流程v0.1

【騰訊Bugly乾貨分享】Android程序招式大全

【騰訊Bugly乾貨分享】Android程序保活招式大全 本文來自於騰訊bugly開發者社群,非經作者同意,請勿轉載,原文地址:http://dev.qq.com/topic/57ac4a0ea374c75371c08ce8 作者:騰訊——張興華 目前市面上的應用,貌似除了微信和手Q都會

Android中的程序(不死程序

Android中的程序保活方式主要分為以下三種: 黑色保活:不同的app程序,用廣播相互喚醒(包括利用系統提供的廣播進行喚醒) 白色保活:啟動前臺Service 灰色保活:利用系統的漏洞啟動前臺Service 黑色保活 利用不同的app程序使用廣播來進

Android程序招數概覽

Android中的程序保活應該分為兩個方面: 提高程序的優先順序,減少被系統殺死的可能性 在程序已經被殺死的情況下,通過一些手段來重新啟動應用程序 本文針對這兩方面來程序闡述,並給出相應的示例。其實主要也是在前人的基礎上做了一個總結,並進行了一些實踐。 閱讀本

android程序實戰(已經上線使用)

https://github.com/08carmelo/android-keeplive 這個我是通過鴻洋的公眾號看到的,我們公司做的是vpn撥號必須要求app保持後臺執行,上面介紹的很詳細,我用的github中使用的程式碼 這個具體需要你自己看 我使用後其實還是有

Android程序招式大全

作者:騰訊——張興華目前市面上的應用,貌似除了微信和手Q都會比較擔心被使用者或者系統(廠商)殺死問題。本文對 Android 程序拉活進行一個總結。Android 程序拉活包括兩個層面:A. 提供程序優先順序,降低程序被殺死的概率B. 在程序被殺死後,進行拉活本文下面就從這兩

Android 程序資料彙總與華為白名單那些事

現在發現App在後臺執行越來越難了。App在華為手機後臺死的非常快,之前看網上說華為有白名單,網上也通過改包名的方式來驗證了。但是半信半疑的,直到諮詢了華為的客服給了一個郵箱 [email protected],回覆的資料 應用加白名單簡化流程v0.1

Android程序精煉詳解

一、前期基礎知識儲備在之前的文章《如何保證Service在後臺不被殺死?》中,筆者分析了為什麼要保活Service、Service的幾種保活方法和Service保活的意義。今天的這篇文章就更進一步,講解程序保活的方法和意義。(1)什麼是程序保活?拿我們的手機應用程式QQ來說,

Android 5.0 以下Native程序嘗試

最近博主嘗試了Android 5.0 以下版本的Native保活機制,感覺收穫頗豐,在此寫下一篇部落格記錄一下。 首先把整個保活流程通過圖片的形式描述下: 首先是AndroidManifest 中註冊的控制元件: <activity androi

如何讓我們的Android應用程序

一、執行緒 程序 應用 預設下,同一個應用的所有元件都執行在同一個程序中。當然也可以在manifest清單檔案中設定元件執行的程序。 元件元素 activity、service、receiver、provider,都有一個process屬性可以指定元

Android之D面試題②程序的一般套路(1畫素Activity/賬號同步/Jobscheduler/系統服務捆綁)

       讀到這裡,你或許有一個疑問,假設現在記憶體不足,空程序都被殺光了,現在要殺後臺程序,但是手機中後臺程序很多,難道要一次性全部都清理掉?當然不是的,程序是有它的優先順序的,這個優先順序通過程序的adj值來反映,它是linux核心分配給每個系統程序的一個值,代表程序的優先順序,程序回收機制就是根據這

Android 2個Service實現相互通過bindservice來實現不通過廣播實現

1,實現原理:啟動2個Service,相互繫結監聽,當A Service監聽到連線斷開的時候,說明B服務可能被 Kill掉了,這時需要重新開啟A服務,同樣B服務的監聽斷掉了,重新啟動A服務。A,B兩個服務都是單獨的程序,需要使用AIDL來通訊。 2,A服務原始碼: public class