定时任务利器:WorkManager库
查看JetPack内容库的时候发现了WorkManager库更新到最新稳定版本2.4.0(2020年8月9号)。WorkManager是Google推出的调度定时任务新技术,官方文档:Docs>Reference>WorkManager">Android Docs>Reference>WorkManager
推荐观看Google技术推广工程师史婧羽小姐姐的WorkManager解说(゜-゜)つロ 干杯~
1、WorkManager
“使用 WorkManager API 可以轻松地调度那些必须可靠地运行的可延期异步任务。通过这些 API,您可以创建任务并提交给 WorkManager,以便在满足工作约束条件时运行。”
1.1、版本
WorkManager推出已经有两年多了,从2018年5月8号的第一个1.0.0-alpha01版本,最新的稳定版本是2.4.0-rc01。到现在经过66个版本的迭代(截止2020年8月9号,不得不吐槽Google。这么频繁的迭代版本,坑太多!!!)
各版本详见: 库 > 版本说明">Jetpack > 库 > 版本说明
1.2、添加到项目
WorkManager并非Frameworks库,需要额外引入到项目才能使用。但是它却能一直向后兼容到API 14,因为内部其实就是根据不同的API利用AlarmManager、JobSchedule等已有的功能二次封装。
dependencies {
...
//WorkManager API 可以轻松地调度那些必须可靠地运行的可延期异步任务。
implementation "androidx.work:work-runtime:2.4.0"
...
}2、WorkManager相关类
要借助WorkManager完成后台定时任务,需要通过辅助的一些类才能完成,这些工具类和WorkManager一起方便的完成定时任务的设置和调度。
2.1、WorkerManager
WorkManager主要管理任务请求和任务队列,将WorkRequest加入任务队列。 通过WorkManager来调度任务,以分散系统资源的负载。获取WorkManager实例:
workManager = WorkManager.getInstance(context);看样子是单例,源码就不在这里跟踪了。
2.2、Worker
Worker是抽象类,只有留了一个抽象方法doWork(),从方法名就能看出是留给开发者实现该方法定义后台任务具体执行的代码。Google的风格总是这样,比如IntentService一样留了一个onHandleIntent(Intent intent)抽象方法给开发者去实现自己的功能。
public class SneakWork extends Worker {
public SneakWork(Context context,WorkerParameters workerParams) {
super(context, workerParams);
}
@Override
public Result doWork() {
//在这里实现后台需要执行的任务代码
return Result.success();
}
}2.3、ListenableWorker.Result
Result类是Worker后台任务执行完之后的返回结果,Result类提供了三类五个方法:
①failure()、failure(Data outputData):任务失败,可携带失败结果,应当使用简单的基本类型或者不超过10kb的Data对象。
②retry():失败并需要重试,由WorkManager自行决定何时重试该任务或者根据Request中的设置来尝试。
③success()、success(Data outputData):任务成功,携带信息。
2.4、WorkerRequest
请求任务。WorkRequest是抽象类,有两个子类OneTimeWorkRequest和 PeriodicWorkRequest,分别用来设置一次性任务和重复执行的任务。通过内部Builder类构造参数需要传入自定义的Work类class创建任务请求对象实例。
OneTimeWorkRequest oneTimeWorkRequest = new OneTimeWorkRequest.Builder(HeavyWork.class)
.build();可以给任务请求设置各种条件,参输入数,时间,约束等。详细方法参考OneTimeWorkRequest.Builder和PeriodicWorkRequest.Builder的API
OneTimeWorkRequest oneTimeWorkRequest = new OneTimeWorkRequest.Builder(HeavyWork.class)
.setInitialDelay(3, TimeUnit.SECONDS)
.addTag("test")
.setConstraints(constraints)
.build();2.5、Constraints
Constraints类给PeriodicWorkRequest任务添加约束条件,比如在充电状态下,有网络状态下才能执行任务等等。Google提供的这个类非常贴心,替开发者考虑各种场景。通过内部的Buidler创建约束对象,再将其通过WorkRequest.Builder的setConstraints(constraints)方法给任务请求添加约束。
Constraints constraints = new Constraints.Builder()
.setRequiresCharging(true) //充电状态
.setRequiresDeviceIdle(false) //设备空闲时运行任务
.setRequiredNetworkType(NetworkType.CONNECTED) //需要有网络连接
.setTriggerContentMaxDelay(5, TimeUnit.SECONDS) //计划更改运行的最大延迟
.build();设置各种条件方法详见Constraints API:Docs>Reference>Constraints.Builder">Android 开发者>Docs>Reference>Constraints.Builder
2.6、WorkInfo
任务状态信息。WorkManager把任务添加到队列后,会给每一个WorkRequest添加一个LiveData,包含任务的状态和信息。LiveData中有WorkInfo对象,利用每个方法的 LiveData 变量,可以通过注册监听器来观察 WorkInfo 的变化。例如,如果您想要在某项工作成功完成后向用户显示消息。
3、WorkManager添加/取消任务
前面的辅助工作都做好了,创建好WorkRequest对象,如何添加到WorkManager中?又如何取消任务呢?
3.1、添加任务
创建好的WorkRequest对象,直接进入交给WorkManager队列。
workManager.enqueue(oneTimeWorkRequest);3.2、取消任务
①通过每个WorkRequest的UUID取消特定的任务请求
UUID uuid = oneTimeWorkRequest.getId();
workManager.cancelWorkById(uuid);②通过给WorkRequest设置定tag取消一组相同tag的任务请求
workManager.cancelAllWorkByTag("tag");4、任务链
WorkManager最出彩的地方在于任务链,多个任务之间可能有前后顺序关系,需要先后或者并发执行完成后,才能继续。
4.1、顺序链式
任务一个接着一个执行
/**
* A
* |
* B
* |
* C
* |
* D
*/
workManager.beginWith(A)
.then(B)
.then(C)
.then(D)
.enqueue();4.2、组合链式
有些任务可以并发执行,但是有些任务组间又需要有先后顺序。通过WorkContinuation类完成任务链的组合。
/**
* A C
* | |
* B D
* | |
* +-------+
* |
* E
*/
WorkContinuation AB= workManager.beginWith(A).then(B);
WorkContinuation CD= workManager.beginWith(C).then(D);
//先组合成一组并发任务链
List<WorkContinuation> list = new ArrayList<>();
list.add(AB);
list.add(CD);
//交付执行
WorkContinuation.combine(list).enqueue();参考资料:
文档 > WorkManager 使用入门">Android 开发者 > 文档 > WorkManager 使用入门
文档 > WorkManager 中的线程处理">Android 开发者 > 文档 > WorkManager 中的线程处理
文档 > WorkManager API">Android 开发者 > 文档 > WorkManager API
Android Jetpack WorkManager">Bilibili > Android Jetpack WorkManager

