Jetpack WorkManager
1. 导航
WorkManager用于应用程序执行任务,即使退出系统,也可以保证运行。- 当应用程序进程消失,
WorkManager不适用于可以安全终止的进程内后台任务。这时使用ThreadPools. WorkManager会根据设备API和包含的依赖项,选择适当的方式安排后台任务,如JobScheduler, Firebase Job Dispatcher 或者 AlarmManager。
2. 基础
2.1 相关类
Worker: 指定要执行的任务。WorkRequest: 代表一项单独的任务。需要指定Worker,也可以向WorkRequest添加具体信息。OneTimeWorkRequest, PeriodicWorkRequest: 一次,还是多次请求。WorkRequest.Builder: 创建WorkRequest的辅助类。Constraints: 指定对任务运行时间的限制。
WorkManager: 管理类。将WorkRequest传递给WorkManager给队列任务。WorkManager调度任务的方式是分散系统资源负载,遵守指定的约束。WorkInfo: 包含有关特定任务的信息。WorkManager提供了LiveData对每个WorkRequest进行监听获取任务状态。
2.2 工作流
- 定义Worker,实现
doWork - 定义WorkRequest,
OneTimeWorkRequestBuilder<Worker>().build() - 执行请求
WorkManager.getInstance().enqueue(workRequest) -
通过LiveData获取执行状态
WorkManager.getInstance().getWorkInfoByIdLiveData(worker.id) .observe(lifecycleOwner, Observer { workInfo -> if (workInfo != null && workInfo.state.isFinished) { // 完成请求 } })
2.3 任务约束
-
WorkRequest设置约束val constraints = Constraints.Builder() .setRequiresDeviceIdle(true) .setRequiresCharging(true) .build() val workRequest = OneTimeWorkRequestBuiler<Worker>() .setConstraints(constraints) .build()
2.4 取消任务
- 在执行请求后可以取消任务。
- 通过
WorkRequest获取ID进行取消。 WorkManager会尽最大努力取消,但不一定能成功。
val requestWorkId: UUID = workRequest.getId()
WorkManager.getInstance().cancelWorkById(requestWorkId)
2.5 标记的任务
- 给
WorkRequest打标签。request.setTag("XXX") - 根据TAG取消所有任务
WorkManager.cancelAllWorkByTag(String) - 根据TAG获取任务执行的状态
WorkManager.getWorkInfosByTagLiveData(String)
2.6 重复的任务
- 使用
PeriodicWorkRequestBuilder创建WorkRequest, ` PeriodicWorkRequestBuilder(12, TimeUnit.HOURS).build()` - 执行
WorkManager.getInstance().enqueue(workRequest)
3. 进阶
3.1 链式任务
- 特定顺序执行多个任务。
WorkManager允许创建和排列指定多个任务的工作序列,以及他们的运行顺序。 -
使用
WorkContinuationWorkManager.getInstance() .beginWith(workRquestA) // WorkContinuation .beginWith(Arrays.asList(workA1, workA2)) // // ...when all A tasks are finished, run the single B task: .then(workRequestB) .then(workRequestC) .enqueue() -
可以创建复杂的chains。
val chain1 = WorkManager.getInstance().beginWith(workA).then(workB) val chain2 = WorkManager.getInstance().beginWith(workC).then(workD) val chain3 = WorkContinuation.combine(Array.asList(chain1, chain2)).then(workE) chain3.enqueue()
3.2 特定的工作顺序
- 使用
beginUniqueWork(String, ExistingWorkPolicy, OneTimeWorkRequest)创建特定的任务顺序。
3.3 输入参数和返回值
WorkRequest.Builder.setInputData(Data)将参数传递给任务。- 观察任务输出的返回值。
Result.success(Data)
4. 从JobDispatcher迁移
WorkManager替代FireBase JobDispatcher
4.1 Gradle设置
dependencies {
def work_version = "1.0.0-beta01"
implementation "android.arch.work:work-runtime:$work_version" // use -ktx for Kotlin+Coroutines
// optional - RxJava2 support
implementation "android.arch.work:work-rxjava2:$work_version"
// optional - Test helpers
androidTestImplementation "android.arch.work:work-testing:$work_version"
}
4.2 从JobService到Workers
- 继承
JobService,在主线程中调用onStartJob,应用程序负责在后台中卸载工作。 WorkManager的基本单元是ListenableWorker,也有其他可用的类型Worker, RxWorker, CoroutinerWorker.ListenableWorker.startWork类似于JobService.onStartJob,也在主线程中调用,返回一个ListenableFuture实例,用于异步发出工作完成信号。这里保证线程安全。ListenableFuture.Result包括success, retry, failure等-
当网络不可用,或者调用
WorkManager.cancel(),或者OS由于其他原因关闭了Worker,onStop会被调用。class MyWorker(appContext: Context, params: WorkerParameters) : ListenableWorker(appContext, params) { override fun startWork(): ListenableFuture<ListenableWorker.Result> { // Do your work here. TODO("Return a ListenableFuture<Result>") } override fun onStopped() { // Cleanup because you are being stopped. } } SimpleJobService映射Worker
4.3 JobBuilder映射到WorkRequest
Job.Builder表示元数据,映射WorkRequest包含OneTimeWorkRequest, PeriodicWorkRequest。Job.Builder.setRecurring(true)对应PeriodicWorkRequest.-
创建
WorkRequestval data = workDataOf("some_key" to "some_val") val constraints: Constraints = Constraints.Builder().apply { setRequiredNetworkType(NetworkType.CONNECTED) setRequiresCharging(true) }.build() val request: OneTimeWorkRequest = OneTimeWorkRequestBuilder<MyWorker>() .setInputData(data) .setInitialDelay(60, TimeUnit.SECONDS) .setBackoffCriteria(BackoffPolicy.EXPONENTIAL, 30000, TimeUnit.MILLISECONDS) .setConstrains(constraints)// 限制 .build()
4.4 调度,取消工作
-
WorkRequest使用唯一的标识,执行调度和取消执行WorkManager.getInstance().enqueueUniqueWork("my-unique-name", ExistingWorkPolicy.KEEP, request) WorkManager.getInstance().cancleUniqueWork("my-unique-name")
4.5 初始化WorkManager
- 在
Application.onCreate中调用WorkManager.initialize()