在日常的开发当中,我们肯定有后台执行任务的需求,使用旧的Android API
会出现电耗消耗比较大的情况,甚至有可能出现被系统推荐优化的软件列表中。在Jetpack
中,Android API
给我们提供了WorkManager
解决后台执行任务的需求,让用户体验和电量消耗
达到一个平衡状态。这篇博客来分享一下WorkManager
相关的知识,希望对看文章的小伙伴有所帮助。
WorkManager的优势
- 针对的是不需要及时完成的任务。
- 能保证任务一定会被执行。WorkManager有自己的数据库,关于任务的所有信息和数据都保存在该数据库中,不管是应用彻底退出还是手机重新启动,它都能完成你的任务。
- 兼容的范围很广,最低能兼容到
Android Level 14
。
WorkManager的兼容方案分析
WorkManager
会根据设备的情况,执行不同的方案。情况分为:
- 在API Level 23以上的设备中,通过
JobScheduler
完成任务; - 在API Level 23以下的设备中,通过
AlarmManager
和Broadcast Receivers
组合来完成任务。
最后还是由Executor
来执行。
WorkManager相关的依赖
Java
版本的依赖:
implementation "androidx.work:work-runtime:2.7.1"
Kotlin+coroutines
的依赖:
implementation "androidx.work:work-runtime-ktx:2.7.1"
RxJava2
的依赖:
implementation "androidx.work:work-rxjava2:2.7.1"
简单的使用
场景是我们需要上传一份文件到服务器,创建一个UploadFileWorker
类,代码如下:
import android.content.Context
import androidx.work.Worker
import androidx.work.WorkerParameters
class UploadFileWorker(context: Context, workerParams: WorkerParameters) :
Worker(context, workerParams) {
override fun doWork(): Result {
return Result.success()
}
}
Result
有下面三种状态:
- 执行成功,
Result.success()
; - 执行失败,
Result.failure()
; - 需要重新执行,
Result.retry()
。
WorkRequest配置任务
1.我们需要设置触发条件,可能是多个条件,代码如下:
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.setRequiresCharging(true)
.setRequiresBatteryNotLow(true)
.build()
2.我们将任务触发条件设置到WorkRequest,代码如下:
val uploadWorkRequest: OneTimeWorkRequest =
OneTimeWorkRequest.Builder(UploadFileWorker::class.java)
.setConstraints(constraints).build()
3.如果你不想立即执行,可以基于上一段代码优化,代码如下:
val uploadWorkRequest: OneTimeWorkRequest =
OneTimeWorkRequest.Builder(UploadFileWorker::class.java)
.setInitialDelay(10,TimeUnit.MINUTES)
.setConstraints(constraints).build()
4.给任务设置标签,方便后续观察,代码如下:
val uploadWorkRequest: OneTimeWorkRequest =
OneTimeWorkRequest.Builder(UploadFileWorker::class.java)
.setInitialDelay(10,TimeUnit.MINUTES)
.addTag("UploadFileWorker")
.setConstraints(constraints).build()
注意如果你想要通过Tag
跟踪任务状态,可以调用WorkManager.getWorkInfosByTagLiveData(String tag)
;取消任务可以调用WorkManager.cancelAllWorkByTag(String tag)
。
5.将任务提交给系统处理,代码如下:
WorkManager.getInstance(this).enqueue(uploadWorkRequest)
观察任务的方法
- WorkManager.getWorkInfosByTag().
- WorkManager.getWorkInfoById().
- WorkManager.getWorkInfosForUniqueWork()。
上面三种不是实时的获取,如果想要实时的获取可以调用下面几种方法:
- WorkManager.getWorkInfosByTagLiveData().
- WorkManager.getWorkInfoByIdLiveData().
- WorkManager.getWorkInfosForUniqueWorkLiveData()
具体的获取代码如下:
WorkManager.getInstance(this).getWorkInfoByIdLiveData(uploadWorkRequest.id)
.observe(this) {
// 任务的状态变化通知
}
取消所有的任务
WorkManager.getInstance(this).cancelAllWork()