天天看点

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