Jetpack系列之WorkManager(二)

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第7天,点击查看活动详情

前言

上一篇我们了解了关于workmanager基本的信息,这一篇我们着重了解一下WorkRequest。

WorkRequest

概览

Work工作是通过WorkManagerenqueue方法将WorkRequest加入执行队列,并在当中进行定义。 WorkRequest作为一个抽象基类,他的两个派生类分别代表两种不同的工作实现, OneTimeWorkRequestPeriodicWorkRequest,前者适用于一次性的工作调度,后者适用于重复性的工作调度。

OneTimeWorkRequest

基本使用

  1. 无约束简单工作
val myWorkRequest = OneTimeWorkRequest.from(MyWork::class.java)

复制代码
  1. 有约束复杂工作
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()构造要传递的数据体,调用setInputDataapi进行传递,可以通过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版本开始引入的概念,主要是用于执行较为重要的任务,这类任务一般存在重要性强、可以在短时间内完成、不受电源管理限制,只要系统当前的负载允许便会执行这类任务。

关于配额: 应用会有各自的前台执行时间配额,它们取决于待机模式存储分区和进程的重要性。

关于配额不足时的政策: 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)
}
复制代码

猜你喜欢

转载自juejin.im/post/7105775601235329060