简介
Android5.0后提供了一个叫JobScheduler的功能,翻译过来叫作业调度器 。它的作用是让系统在某个时刻某个特定条件下批处理一些APP的任务请求,而且这项任务的执行是在你自己的应用程序进程中。
JobInfo和JobInfo.Builder
JobScheduler的工作由JobInfo对象进行封装,并由它来指定调度条件,当符合条件时,系统将执行调度在您的应用程序Jobservice。它的一些方法调用,可以参考官方文档:https://developer.android.com/reference/android/app/job/JobInfo.html。
JobInfo.Builder 类配置调度的任务执行方式。你可以将任务调度为在特定的条件下运行,常见的条件如:
设备空闲时执行任务
setRequiresDeviceIdle(true)
设备充电时执行任务
setRequiresCharging(true)
设备满足网络条件时执行任务
setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)
其中,
NETWORK_TYPE_NONE:不管是否有网络都执行
NETWORK_TYPE_ANY:任何一种网络都执行
NETWORK_TYPE_UNMETERED非移动网络才执行)
设备重启后是否还需执行任务
setPersisted(true)
注意,设置这方法时需RECEIVE_BOOT_COMPLETED权限
间隔一定时间执行任务
setPeriodic(longminLatencyMillis)
延迟一定时间执行任务
setMinimumLatency(longminLatencyMillis)
注意,该方法不可与setPeriodic同用,否则会异常
最晚延迟时间执行任务,即使条件不满足
setOverrideDeadline(longmaxExecutionDelayMillis)
注意,该方法不可与setPeriodic同用,否则会异常
等等,更多方法使用和详细介绍,可参考官方文档:https://developer.android.com/reference/android/app/job/JobInfo.Builder.html。好了,唠叨了这么多,下面我们来看看实例代码的实现吧
创建JobScheduler
第一步,创建一个继承于JobService的Service,并实现两个必要方法onStartJob和onStopJob,此类就是系统给我们执行调用的地方:
public class MyJobService extendsJobService {
private static final String TAG = "MyJobService";
@Override
public boolean onStartJob(final JobParameters params) {
Log.e(TAG, "onStartJob:" +params.getJobId());
if (true) {
new Thread(new Runnable() {
@Override
public void run() {
try {
//模拟耗时
Thread.sleep(2000);
} catch (Exception e) {
e.printStackTrace();
}
jobFinished(params, false);
}
});
// 任务运行需要在线程内一定时间才能执行完成,那么先返回true,同时要在线程完成时调用jobFinished方法
return true;
}
// 任务运行不需要长时间等待,直接可处理完成就应该返回false
return false;
}
@Override
public boolean onStopJob(JobParameters params) {
Log.i(TAG, "onStopJob:" + params.getJobId());
return false;
}
}
AndroidManifest.xml:
<service
android:name="project.test.com.jobschedulerdemo.MyJobService"
android:permission="android.permission.BIND_JOB_SERVICE" >
</service>
说明
onStartJob方法中,若要执行的任务运行不需要长时间等待,直接可处理完成就应该返回false;否则,任务运行需要在线程内一定时间才能执行完成,那么先返回true,同时要在线程完成时调用jobFinished方法。
第二步,在Activity中起动JobScheduler:
public class MainActivity extends Activity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btn = (Button) findViewById(R.id.btn_start_job);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startJobScheduler();
}
});
}
private void startJobScheduler() {
ComponentName jobService = new ComponentName(this, MyJobService.class);
JobScheduler scheduler = (JobScheduler)getSystemService(Context.JOB_SCHEDULER_SERVICE);
for (int jobId = 0; jobId < 10; jobId ++) {
JobInfo jobInfo = new JobInfo.Builder(jobId, jobService)
// .setRequiresDeviceIdle(true) // 设置空闲时执行任务
// .setRequiresCharging(true) // 设置充电时执行任务
// .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED) // 设置不管有无网络都执行任务
// .setMinimumLatency(5000) // 设置延迟一定时间执行任务
// .setOverrideDeadline(60000) // 设置最晚延迟时间执行任务
.setPersisted(true) // 设置重启后是否还需执行任务
.setPeriodic(5000) // 间隔5秒执行任务
.build();
scheduler.schedule(jobInfo);
}
}
}
说明
startJobScheduler方法首先获得了一个JobScheduler对象,然后模拟创建了10个要执行的任务,每个循环中创建一个JobInfo对象,并指定执行类为MyJobService。最后调用了schedule来执行相应任务操作,如若取消一个任务,可以使用scheduler.cancel(jboId);。
拉活机制
JobScheduler和我们前面介绍Android帐户(《Android里帐户同步的实现》)一样,它们都是可以系统后台自动触发的一种机制。正因为这样,所以它们都能将已经退出或完全结束的APP在系统触发机制的情况下能再次被拉活起来。当然由于国内手机厂商的各种订制和阉割,并不是所有厂商手机系统都能够实现这种拉活机制,像小米手机上是验证行不通的,大家有兴趣可以自行去尝试。
总结
本文只为简单介绍和演示JobScheduler的实现步骤,更多介绍可以往官网查看相应知识:
https://developer.android.com/reference/android/app/job/JobScheduler.html
https://developer.android.com/reference/android/app/job/JobInfo.html
https://developer.android.com/reference/android/app/job/JobInfo.Builder.html
另外上面介绍的Demo源码可以点击这里下载