天天看點

android service灰色保活

**

使用場景

**

自助裝置遠端管理上報裝置故障資訊,接收伺服器指令,

使用的事webSocket,需要啟動service,并且服務要盡量保活;

**

保活手段

**

目前業界的Android程序保活手段主要分為** 黑、白、灰 **三種,其大緻的實作思路如下:

黑色保活:不同的app程序,用廣播互相喚醒(包括利用系統提供的廣播進行喚醒)

白色保活:啟動前台Service

灰色保活:利用系統的漏洞啟動前台Service

本文主要介紹灰色保活,黑色保活主要監聽系統廣播;白色保活類似QQ音樂,導航欄顯示通知;灰色保活實際上也是将Service設定為前台服務,不過将通知欄屏蔽了,這樣在使用者無感的情況将将服務的優先級提高到前台服務的級别,在系統記憶體不足時,也不會被kill掉;

**

代碼實作

**

對于 API level < 18 :調用startForeground(ID, new Notification()),發送空的Notification ,圖示則不會顯示。

對于 API level >= 18:在需要提優先級的service A啟動一個InnerService,兩個服務同時startForeground,且綁定同樣的 ID。Stop 掉InnerService ,這樣通知欄圖示即被移除。

//定義一個灰色保活service 
    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);
        }
        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }
    }

@Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG,"onStartCommand");
        //初始化websocket
        initSocketClient();
        mHandler.postDelayed(heartBeatRunnable, HEART_BEAT_RATE);//開啟心跳檢測

        //設定service為前台服務,提高優先級
        if (Build.VERSION.SDK_INT < 18) {
            //Android4.3以下 ,隐藏Notification上的圖示
            startForeground(GRAY_SERVICE_ID, new Notification());
        } else if(Build.VERSION.SDK_INT>18 && Build.VERSION.SDK_INT<25){
            //Android4.3 - Android7.0,隐藏Notification上的圖示
            Intent innerIntent = new Intent(this, GrayInnerService.class);
            startService(innerIntent);
            startForeground(GRAY_SERVICE_ID, new Notification());
        }else{
            //Android7.0以上app啟動後通知欄會出現一條"正在運作"的通知
            startForeground(GRAY_SERVICE_ID, new Notification());
        }
        return START_STICKY;
    }