持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第7天,点击查看活动详情
前言
上一篇我们了解了关于workmanager基本的信息,这一篇我们着重了解一下WorkRequest。
WorkRequest
概览
Work
工作是通过WorkManager
中enqueue
方法将WorkRequest
加入执行队列,并在当中进行定义。 WorkRequest
作为一个抽象基类,他的两个派生类分别代表两种不同的工作实现, OneTimeWorkRequest
和 PeriodicWorkRequest
,前者适用于一次性的工作调度,后者适用于重复性的工作调度。
OneTimeWorkRequest
基本使用
- 无约束简单工作
val myWorkRequest = OneTimeWorkRequest.from(MyWork::class.java)
复制代码
- 有约束复杂工作
val myWorkRequest: WorkRequest =
OneTimeWorkRequestBuilder<MyWork>()
// 约束配置项
.build()
复制代码
单次任务
继承于Worker,实现doWork()异步方法。doWork() 返回的Result会通知 WorkManager任务是否成功,以及任务失败时是否应重试任务。
关于工作结果: Result.success()
:任务执行成功。 Result.failure()
:任务执行失败。 Result.retry()
:任务执行重试,根据其重试政策在其他时间尝试
基本使用
// 构建任务
val myWorkRequest = OneTimeWorkRequest.from(MyWork::class.java)
// 提交任务
WorkManager.getInstance(this).enqueue(myWorkRequest)
class MyWorker : Worker() {
override fun doWork(): Worker.WorkerResult {
todo()//执行任务
return Worker.WorkerResult.SUCCESS
}
}
复制代码
任务数据传递
通过Data.Builder()
构造要传递的数据体,调用setInputData
api进行传递,可以通过getWorkInfoByIdLiveData
去观察数据。
基本使用
//要发传递出去的数据
val inputData = Data.Builder().putString("inputData", " inputData").build()
//构建WorkRequest
val myWorkRequest = OneTimeWorkRequest.Builder(Worker::class.java)
.setInputData(inputData).build()//设置要传递的数据
// 提交任务
WorkManager.getInstance(this).enqueue(myWorkRequest)
//通过LiveData接收返回的数据
WorkManager.getInstance(this).getWorkInfoByIdLiveData(myWorkRequest.id)
.observe(this) {
//当状态处于完成时,也就是SUCCEEDED、FAILED、CANCELLED时,任务才结束,才能去拿结果数据,不然获取到的数据是null
if (it.state.isFinished) {
todo()
}
}
复制代码
定时任务
//执行定时任务
val work1 =
OneTimeWorkRequest.Builder(MyWork1::class.java)
//1分钟后执行,还有其他指定单位(毫秒/秒/分钟/小时/天)
.setInitialDelay(1, TimeUnit.MINUTES)
.build()
WorkManager.getInstance(this).enqueue(work1)
复制代码
多任务执行
workmanager提供了链式任务执行api,主要是方便开发者进行关联性任务的调用问题。
//执行多个后台任务-集合方式
binding.button4.setOnClickListener {
val work1 =
OneTimeWorkRequest.Builder(MyWork1::class.java).build()
val work2 =
OneTimeWorkRequest.Builder(MyWork2::class.java).build()
val work3 =
OneTimeWorkRequest.Builder(MyWork3::class.java).build()
// 可以将多个任务放到集合当中
val list = mutableListOf<OneTimeWorkRequest>()
oneTimeWorkRequests.add(work2)
oneTimeWorkRequests.add(work3)
//先执行1,再执行2,3
WorkManager.getInstance(this).beginWith(work1)
.then(list)
.enqueue()
}
复制代码
加急任务
加急任务是在2.7.0版本开始引入的概念,主要是用于执行较为重要的任务,这类任务一般存在重要性强、可以在短时间内完成、不受电源管理限制,只要系统当前的负载允许便会执行这类任务。
关于配额: 应用会有各自的前台执行时间配额,它们取决于待机模式存储分区和进程的重要性。
![](/qrcode.jpg)
关于配额不足时的政策: OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST
- 配额不足时会导致作业作为普通工作请求运行。 OutOfQuotaPolicy.DROP_WORK_REQUEST
- 会在配额不足时导致加急任务取消。
基本使用:
val request = OneTimeWorkRequestBuilder()
.setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
.setForeground(true) // Android 12 或更高版本为目标平台时可以使用,但是不建议,建议在work当中实现
.build()
class MyWorker : CoroutineWorker() {
override suspend fun doWork(): Result = coroutineScope {
todo()//执行任务
Worker.WorkerResult.SUCCESS
}
// 实现通知
override suspend fun getForegroundInfo(): ForegroundInfo {
return ForegroundInfo(notificationId, NotificationCompat.Builder(applicationContext, channelId)
.setSmallIcon(R.drawable.logo)
.setContentTitle("标题")
.setContentText("描述")
.setPriority(NotificationCompat.PRIORITY_DEFAULT).build()
)
}
}
复制代码
PeriodicWorkRequest
基本使用
//重复周期最少设置15分钟,
val work = PeriodicWorkRequest.Builder(MyWork::class.java, 15, TimeUnit.MINUTES).build()
//监听状态和数据变化
WorkManager.getInstance(this).getWorkInfoByIdLiveData(work.id)
.observe(this) {
if (it.state.isFinished) {
...
}
}
//提交任务,任务加入队列
WorkManager.getInstance(this).enqueue(periodicWorkRequest)
}
复制代码