**
使用场景
**
自助设备远程管理上报设备故障信息,接收服务器指令,
使用的事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;
}