JobScheduler是Android5.0 开始引入了一个新系统服务。它将后台任务调度直接交给系统服务(JobSchedulerSevice)管理,并且可以设置许多约束条件,如周期调度,延迟调度,网络连接,电源插入,还有AndroidL引入的空闲模式,在条件符合的情况下,系统服务BindService的方式把应用内Manifest中配置的JobService启动起来,并通过进程间通信Binder方式调用JobService的onStartJob、onStopJob等方法来进行Job的管理。即便在执行任务之前应用程序进程被杀,也不会导致任务中断,Jobservice不会因应用退出而退出,但确实是运行在该应用进程中。
JobInfo.Builder配置介绍
构造函数:JobInfo.Builder(int jobId, ComponentName jobService)
参数说明
int jobId
按照官方文档说jobId该标识符在相同的uid的所有客户端中必须是唯一的(即在该设备上必须是唯一的)。为了保证在应用升级后也是稳定的,因此建议不要基于资源id进行设置 。ComponentName jobService
用来处理该任务的应用内服务service的ComponentName,系统服务会依此启动该服务
重要方法配置参数
//设置开机启动 builder.setPersisted(true); //设置失败后重试间隔时间和策略 //BACKOFF_POLICY_LINEAR: initial_backoff_millis * num_failures 延迟时间等于乘以次数 //BACKOFF_POLICY_EXPONENTIAL:initial_backoff_millis * 2 ^ (num_failures - 1) 延迟时间等于乘以2的次数幂 builder.setBackoffCriteria(30000, BACKOFF_POLICY_LINEAR); //设置设备空闲时候执行 与上述重试策略违背,不能同时设置 builder.setRequiresDeviceIdle(boolean requiresDeviceIdle) //设置任务的周期性 builder.setPeriodic(3000); //设置延迟时间,与周期性设置是相违背的,同时设置会抛异常IllegalArgumentException builder.setMinimumLatency(long minLatencyMillis) builder.setOverrideDeadline(long maxExecutionDelayMillis) //设置网络类型下 NETWORK_TYPE_UNMETERED指不计流量的网络 即wifi builder.setRequiredNetworkType(NETWORK_TYPE_UNMETERED); //设置充电下执行 builder.setRequiresCharging(true); //设置首次执行前最大延迟时间 builder.setTriggerContentMaxDelay(1000);
注意上述配置中存在互斥条件,不能同时存在,否则会抛出异常,如下:
builder.setBackoffCriteria()与builder.setRequiresDeviceIdle() builder.setPeriodic()与builder.setMinimumLatency()、 builder.setOverrideDeadline()
调度JobInfo注册到系统服务JobSchedulerService
只要通过JobScheduler.schedule方法就可以完成:
JobInfo.Builder builder = new JobInfo.Builder(jobId, new ComponentName(this, MyJobService.class));JobScheduler jobScheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE); jobScheduler.schedule(builder.build());
Jobservice配置
在manifest中配置必须加上权限属性android.permission.BIND_JOB_SERVICE,否则系统服务将忽视。
<service android:name=".MyJobService" android:permission="android.permission.BIND_JOB_SERVICE"></service>
MyJobService代码很简单,主要是为了测试功能:
public class MyJobService extends JobService { @Override public void onCreate() { super.onCreate(); Log.i("chuan", "onCreate"); } @Override public int onStartCommand(Intent intent, int flags, int startId) { super.onStartCommand(intent, flags, startId); Log.i("chuan", "onStartCommand"); return START_STICKY; } @Override public boolean onStartJob(JobParameters params) { Log.i("chuan", "onStartJob"); Toast.makeText(this, "onStartJob", Toast.LENGTH_LONG).show(); return false; } @Override public boolean onStopJob(JobParameters params) { Log.i("chuan", "onStopJob"); return false; } }
运行日志如下:
06-09 11:41:43.127 25637-25637/cn.com.account.demo1 I/chuan: onCreate
06-09 11:41:43.143 25637-25637/cn.com.account.demo1 I/chuan: onStartJob
06-09 11:42:30.390 25637-25637/cn.com.account.demo1 I/chuan: onCreate
06-09 11:42:30.394 25637-25637/cn.com.account.demo1 I/chuan: onStartJob
06-09 11:42:47.588 25637-25637/cn.com.account.demo1 I/chuan: onCreate
06-09 11:42:47.591 25637-25637/cn.com.account.demo1 I/chuan: onStartJob
即使应用退出,依然可以作为后台进程运行着,定期执行启动jobService执行任务。
应用场景
1、通过JobScheduler来安排一个后台进程,在之前的进程保活自启动那边文章中就提到过可以用来作为进程唤起的手段。
通过配置周期性调度启动任务Job,并在MyJobService中onStartJob进行判断目标进程是否存在,不存在就启动,代码很简单就不贴了。
//设置任务的周期性 builder.setPeriodic(3000);
2、处理一些耗电的任务,设置充电模式下启动,来完成一些耗电后台进程任务
//设置充电下执行
builder.setRequiresCharging(true);
3、处理一些耗流量任务,设置在不计流量情况下启动,如上传失败的缓存日志,检查更新下载Apk
//设置网络类型下 NETWORK_TYPE_UNMETERED指不计流量的网络 即wifi
builder.setRequiredNetworkType(NETWORK_TYPE_UNMETERED);
4、处理一些耗内存的任务,设置在手机空闲模式下
//设置设备空闲时候执行 与上述重试策略违背,不能同时设置
builder.setRequiresDeviceIdle(boolean requiresDeviceIdle)