如何讓安卓APP一直在後臺運行?

本文摘自微信公衆號“android高心星的私塾”微笑

    一  聲明

        1 網上很多的保活手段,但是不靠譜的居多
        2 本文只是進行保活知識的推廣,不是在教你做永生不死的進程

    二  保活手段

        1 業界保活手段:黑色保活,灰色保活,白色保活

        2 黑色保活:

            1  不同的APP進程,用廣播相互喚醒,包括利用系統廣播進行喚醒
            2  常見手段:
                    1 開機,網絡切換,拍照,拍視頻等利用系統廣播喚醒APP
                        此場景Google已經意識到,在Android N 取消了 拍照,視頻,網絡切換的廣播
                    2 接入第三方的SDK也會喚醒相應的APP進程
                    3 假如你手機裏裝了支付寶,淘寶,UC等阿里系的APP,那麼你打開任何一個,都有可能喚醒其他的阿里系的APP

        3 白色保活:

             就是調用系統的API啓動一個前臺Service進程,這樣會在通知欄生成一個Notification,用戶知道哪些進程正在運行

        4 灰色保活

            1 保活領域應用最爲廣泛,利用系統的漏洞來啓動一個前臺的Service進程,與“白色保活”不同的是,它不會在通知欄生成一個Notification,用戶無法察覺,但是優先級要高於普通的後臺進程。
            2 實現思路
                思路一:當API<18,啓動前臺的Service直接傳入new Notification();
                思路二:當API >= 18,同時啓動兩個id相同的前臺Service,然後再將後啓動的Service做stop處理
                代碼這樣寫:
import android.app.Notification;
import android.app.Service;
import android.content.Intent;
import android.os.Build;
import android.os.IBinder;

/**
 * APP灰色保活
 * Created by fflin on 2016/4/23.
 */
public class GrayService extends Service {
    private final static int GRAY_SERVICE_ID = 1001;

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        //API < 18,此方法能有效地隱藏notification的圖標
        if (Build.VERSION.SDK_INT < 18) {
            startForeground(GRAY_SERVICE_ID, new Notification());
        } else {
            Intent intent1 = new Intent(this, GrayInnerService.class);
            startService(intent1);
            startForeground(GRAY_SERVICE_ID, new Notification());
        }
        return super.onStartCommand(intent, flags, startId);
    }


    //給API >= 18 的平臺上做灰色保護手段
    public class GrayInnerService extends Service {
        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }


        @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);
        }
    }


}


            3 檢驗方法:
                首先看系統通知欄有沒有Notification,如果沒有,就進入手機adb shell模式,輸入命令dumpsys activity services PackageName
                打印出指定包名的所有進程中的service信息,看下有沒有isForground=true的信息,如果有,就說明了該APP使用了灰色保活
            4 使用灰色保活手段並不意味着你的應用就能永生不死,只能說提高了進程的優先級,如果應用佔用了很大的內存,還是會被回收的

  三  進一步理解保活

            進程回收機制 
                系統出於體驗和性能上的考慮,APP在退出後臺時系統並不會真正的kill掉這個進程,而是將其緩存起來,打開的應用越多,後臺緩存的進程也就越多。在系統內存不足的情況下,系統開始根據自身的一套進程回收機制來判斷要回收掉哪些進程,這套殺死進程回收內存的機制叫 Low Memory Killer,它是基於Linux內核的OOM killer機制誕生的,該機制爲每個系統分配了一個值,叫做oom_adj,代表了進程的優先級,oom_adj越大,代表優先級越低,越容易被回收,普通APP進程的oom_adj >=0,系統的可能會小於0.
        2 查看oom_adj的值,需要用到兩個shell命令
            ps | grep 包名
            $cat /proc/進程id/oom_adj
        3 結果發現,APP推到後臺,UI進程的值降低最爲明顯,因爲它佔用的內存資源最多,因此,爲了避免後臺UI進程被殺,需要儘可能的釋放一些不用的圖片,音頻資源     

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