简述

android系统在内存不足会回收一些后台服务,保证系统的流畅运行,对于service的进程保活也违反了android系统对于内存回收机制的原则性,我们下列所做的只能增强service在系统的存活率,真正做到永驻后台服务

service的基础

要了解service保活必须首先了解service的基础,关于service的启动方式以及service的生命周期,这点并不在我们这里的范围之内,我们可以参考郭神的博客 Android Service完全解析,关于服务你所需知道的一切

关于service提升保活的几种方式

  1. 提升service的优先级
  2. 在service的onDestory()方法开启服务
  3. 修改onStartCommand()方法中的返回值
  4. 利用系统广播进行拉活
1.提升service的优先级

在Activity的生命周期中,我们可以了解到关于系统的进程优先级分为前台进程->可见进程->service进程->后台进程->空进程,因为service处于第三级别,我们可以在serivce中增加startForeground()方法。来提升service的优先级.
示例代码:

@Override
    public void onCreate() {
        super.onCreate();
        Notification.Builder builder = new Notification.Builder(this);
        builder.setSubText("测试1");//添加通知的子标题
        builder.setSmallIcon(R.mipmap.ic_launcher);//设置通知的图标
        builder.setContentText("测试内容");//添加内容
        Notification notification =builder.build();
        startForeground(1,notification);
        Toast.makeText(this,"开启服务",Toast.LENGTH_LONG).show();

    }

屏幕的上面会出现项目的小图标,从而提升service为可见进程.

2.在service的onDestory()方法开启服务

当用户查看后台运行的服务的时候,手动终止此服务,app应用会走onDestory()的方法,所以我们可以在此方法中继续开启服务。

@Override
    public void onDestroy() {
        super.onDestroy();
        Log.e("serviceTest","onDestroy");
        startService(new Intent(this,ServiceTest.class));//开启服务
    }
3.修改onStartCommand()方法中的返回值

通过官方文档我们可以了解到onStartCommand()会有一个int的返回值,其返回值源码提供了4个返回值。
这四个返回值:start_sticky、start_no_sticky、START_REDELIVER_INTENT、START_STICKY_COMPATIBILITY。
它们的含义分别是:
1):START_STICKY:如果service进程被kill掉,保留service的状态为开始状态,但不保留递送的intent对象。随后系统会尝试重新创建service,由于服务状态为开始状态,所以创建服务后一定会调用onStartCommand(Intent,int,int)方法。如果在此期间没有任何启动命令被传递到service,那么参数Intent将为null。
2):START_NOT_STICKY:“非粘性的”。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统不会自动重启该服务
3):START_REDELIVER_INTENT:重传Intent。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入。
4):START_STICKY_COMPATIBILITY:START_STICKY的兼容版本,但不保证服务被kill后一定能重启。

@Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.e("serviceTest","onStartCommand");
        return START_STICKY;
    }

从上面讲述我们可以了解到START_STICKY或者START_STICKY_COMPATIBILITY的返回值都具备尝试重新创建service。

4. 利用系统广播进行拉活

我们都可以了解到关于android系统在各个状态下的改变都会发送一个对应的广播。

android 保活 通知栏 android保活机制service_保活


我们可以在androidMainifest()的清单文件中接受这些常用的广播

<receiver android:name=".WifiBroadCastReceiver"
            android:exported="true">
            <intent-filter>
                <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
            </intent-filter>
        </receiver>

所使用的权限:

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.WRITE_SETTINGS"/>

然后在onRevice()方法接受这些广播来启动service

public class WifiBroadCastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if(ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())){
            Log.e("serviceTest","网络变化了");
            context.startService(new Intent(context,ServiceTest.class));
        }
    }
}

总结

以上是较为常用的service保活机制,当然我们还可以通过:
JobScheduler机制来拉活service,推荐:
JobService和JobScheduler机制在Android5.0以上保活