简述
android系统在内存不足会回收一些后台服务,保证系统的流畅运行,对于service的进程保活也违反了android系统对于内存回收机制的原则性,我们下列所做的只能增强service在系统的存活率,真正做到永驻后台服务
service的基础
要了解service保活必须首先了解service的基础,关于service的启动方式以及service的生命周期,这点并不在我们这里的范围之内,我们可以参考郭神的博客 Android Service完全解析,关于服务你所需知道的一切
关于service提升保活的几种方式
- 提升service的优先级
- 在service的onDestory()方法开启服务
- 修改onStartCommand()方法中的返回值
- 利用系统广播进行拉活
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系统在各个状态下的改变都会发送一个对应的广播。
我们可以在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以上保活