WorkManager 可以更容易的执行可延迟的异步任务,可以创建一个任务交给 WorkManager 立即执行或者在合适的时间执行。WorkManager 会自己选择一个合适的方式运行任务,当 App 在前台运行时,WorkManager 会在一个新的线程中运作该任务;如果 App 没有运行,可以不用谢任何逻辑代码,WorkManager 就可以根据项目的依赖以及设备 API 级别选择一个合适的方式运行任务,WorkManager 可以用 JobScheduler
, Firebase JobDispatcher
或者 AlarmManager
WorkManager 还有一个惊人的功能,在退出程序后依然能够运行之前添加的任务
利用 WorkManager 可以很容易的把一个在指定条件下才执行的任务交给系统运行,WorkManager 需要 compileSdk
版本至少为 28 才能使用:
1 | dependencies { |
下面是 WorkManage 中几个比较重要的类:
Worker
:用来执行任务的类,这是一个抽象类,需要继承该类WorkRequest
:定义一个任务,可以指定用哪个Worker
来执行该任务,也可以添加执行该任务的条件。每一个WorkRequest
都会生成一个唯一 ID;可以使用这个 ID 取消任务或者获取任务当前状态,这也是一个抽象类,它有两个子类可以使用,OneTimeWorkRequest
和PeriodicWorkRequest
,从命名上就能区分出来两个类的区别,一个执行单次任务,一个执行循环任务WorkRequest.Builder
:如果不想用定义好的子类,同样也可以利用它来创建一个WorkRequest
Constraints
:用来指定任务运行的条件,通过Constraints.Builder
来创建,在创建WorkRequest
之前把Constraints
传递给WorkRequest.Builder
即可
WorkManager
:存放和以及管理任务WorkStatus
:包含任务的一些信息,WorkManager
会为每一个WorkRequest
提供一个LiveData
,该LiveData
持有一个WorkStatus
对象,观察该LiveData
就能获取任务当前状态以及返回值
基本用法
执行任务
项目中需要定时检测本地日志文件的大小,如果过大就删除。之前的解决方案用的是 RxJava 的 interval
操作符,现在换成使用 WorkManager
看看有什么区别,首先定义一个继承了 Worker
的类:
1 | class CheckFileSizeWorker : Worker() { |
doWork
函数的返回值中一共有三个状态 Result.SUCCESS
、Result.FAILUER
和 Result.RETRY
1 | val checkFillSizeWorker = OneTimeWorkRequest.Builder(CheckFillSizeWorker::class.java).build() |
获取状态
使用 OneTimeWorkRequest
创建一个任务,如果不指定一个执行条件,这个任务会立即执行,可以通过这个任务的 ID 来获取该任务的状态:
1 | WorkManager.getInstance().getStatusById(checkFillSizeWorker.id) |
如果使用
PeriodicWorkRequest
来执行循环任务,有几个问题需要注意。它默认循环的最小间隔是15分钟,其中还有一个 叫做 flexInterval
的参数,最小间隔是5分钟,且不能超过循环间隔时间。这个参数是用来指定一个弹性时间,举个栗子说明一下,如果使用默认的参数,那么这个循环任务其实不是刚好过15分钟就执行,而是通过循环间隔时间减去这个弹性时间,也就是10分钟后才是任务开始执行的时间,WorkManager
会在前一个任务结束的10分钟到15分钟之间执行下一个任务
设置执行条件
接下来给这个任务指定一个执行条件,这个时候就需要用到 Constraints
这个类了:
1 | // 还有电量是否低,是否正在充电,设备是否空闲等条件 |
取消任务
通过任务的 ID 来取消该任务:
1 | WorkManager.getInstance().cancelWorkById(checkFillSizeWorker.id) |
如果想要取消一组任务,需要给这些任务指定了一个 tag,通过
cancelAllWorkByTag
函数来取消
评论