如何使用WorkManager执行后台任务(下)
0x00 WorkManager的高级用法
在上一文中已经了解到 WorkManager
的基本用法之后,今天来看看它的一些高级用法:
- 链式任务调用
- 唯一任务序列
- 传递参数和获取返回值
0x01 链式任务(Chained tasks)
WorkManager
在执行多个工作任务的时候,可以指定执行顺序。假设一个应用程序中有3个 OneTimeWorkRequest
对象: workA
、 workB
、 workC
。这几个任务需要按照顺序执行,那么可以使用 WorkManager.beginWith()
方法加入 workA
,这时候会返回一个 WorkContinuation
对象,它定义了工作任务的执行序列。然后通过它再调用 WorkContinuation.then()
把 workB
和 workC
加入到执行队列中,最后执行 WorkManager.enqueue()
方法。
WorkManager.getInstance() .beginWith(workA) // Note: WorkManager.beginWith() returns a // WorkContinuation object; the following calls are // to WorkContinuation methods .then(workB) // FYI, then() returns a new WorkContinuation instance .then(workC) .enqueue()
WorkManager
会按照指定的顺序来执行 workA
、 workB
、 workC
。如果其中有一个工作任务执行的时候返回 Worker.Result.FAILURE
,那么整个执行序列就会停止。
WorkManager.beginWith()
方法可以传递多个 Worker
对象,表示可以并行执行的任务组,然后再调用 then()
方法。当这并行任务组都执行完之后才会执行接下来 then
中的工作任务。
WorkManager.getInstance() // 首先,并行执行workA1,workA2,workA3这三个任务 .beginWith(workA1, workA2, workA3) // 当三个任务都完成之后, 开始执行workB: .then(workB) // 最后再并行执行 workC1,workC2 .then(workC1, workC2) .enqueue()
还可以通过 WorkContinuation.combine()
方法创建更加复杂的链接任务调用序列。它可以将两个 WorkContinuation
对象合并,假设要调用如下的任务序列:
val chain1 = WorkManager.getInstance() .beginWith(workA) .then(workB) val chain2 = WorkManager.getInstance() .beginWith(workC) .then(workD) val chain3 = WorkContinuation .combine(chain1, chain2) .then(workE) chain3.enqueue()
这个链式执行顺序是:子链 A->B 与子链 C->D 并行执行的, workA
执行后再执行 workB
,以及 workC
执行后执行 workD
;然后等待 workB
以及 workD
都执行完,最后执行 workE
。
需要注意的是, WorkManager
无法保证两个子链的执行顺序,有可能 chain1
比 chain2
快,也有可能是 chain1
比 chain2
慢。
0x02 唯一任务序列(Unique work sequences)
在应用程序开发中,可能会多次把同一个链式任务添加到 WorkManager
中,但希望只有一个链式任务在执行,这时候可以使用唯一任务序列对链式任务指定处理规则。假设,做一个下载文件操作,对一个文件下载链接,我们不需要重复下载,只需要添加一次,后面再添加这个任务,就忽略掉,因为我们不希望重复多次下载同一个文件。所以当添加两个同样名称为"download"操作任务时,对于唯一任务序列来说,可以通过 ExistingWorkPolicy
中的 REPLACE
, KEEP
和 APPEND
,来指定添加的策略。
- REPLACE:新任务将替换旧的
- KEEP:新任务会被丢弃,旧的任务会被保持
- APPEND:追加,旧任务执行之后再执行新的任务。
使用 beginUniqueWork()
方法可以创建任务序列,并且可以指定唯一的一个名称(name)。然后再 ExistingWorkPolicy
指定任务的替换策略
WorkContinuation continuation = mWorkManager .beginUniqueWork("download", ExistingWorkPolicy.KEEP, OneTimeWorkRequest.from(CleanupWorker))
0x03 传递参数和获取返回值
任务执行可以传递参数以及获取到任务执行的结果。使用 WorkRequst.Builder.setInputData()
方法传递一个 Data
对象,它是key-value形式的对象,使用 Data.Builder
来创建。在 Worker
类中可以使用 Worker.getInputData()
获取到参数。
同样地,在 Worker
中可以使用 Worker.setOutputData()
设置一个 Data
对象的返回值。要获取到这个返回值就通过 LiveData<WorkStatus>
。
举个栗子:
有一个下载任务,在 Worker
中获取传递过来的参数url,然后执行下载,最后设置下载结果。
// the result key: const val KEY_RESULT = "result" class DownloadWorker(context : Context, params : WorkerParameters) : Worker(context, params) { override fun doWork(): Result { // 获取参数 val url = getInputData("url") // 执行下载 val result = download(url); // 设置下载结果 val output: Data = mapOf(KEY_RESULT to result).toWorkData() setOutputData(output) // 任务执行成功 return Result.SUCCESS } }
然后,通过 WorkRequest
传递参数
// 构造下载链接参数 val urlData: Data = mapOf("url" to "https://developer.android.com/images/topic/libraries/architecture/workmanager-chain.svg") .toWorkData() // 构造WorkRequest并传递下载参数 val downloadWork = OneTimeWorkRequest.Builder<DownloadWorker>() .setInputData(urlData) .build() // 交给WorkManager执行任务 WorkManager.getInstance().enqueue(downloadWork)
最后,通过 WorkStatus
获取返回值
WorkManager.getInstance().getStatusById(downloadWork.id) .observe(this, Observer { status -> if (status != null && status.state.isFinished) { val myResult = status.outputData.getString(KEY_RESULT, myDefaultValue) // ... do something with the result ... } })
0x04 引用
https://developer.android.com/topic/libraries/architecture/workmanager/advanced
https://developer.android.com/reference/androidx/work/ExistingWorkPolicy
http://clmirror.storage.googleapis.com/codelabs/android-workmanager/index.html?index=..%2F..%2Findex#0

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
如何使用WorkManager执行后台任务(上)
0x00 简述 WorkManager 是 Android Jetpack中的一部分,它主要是封装了 Android 后台任务的调度逻辑。在前文《Android后台任务处理指南》一文中知道,WorkManager 是高级 API,它实际是封装了JobScheduler, Firebase JobDispatcher, 和 AlarmManager 底层的使用,提供了简单且灵活易用的API,它有很多优势: 支持异步一次性或周期任务 支持网络、存储空间以及电量状态等约束 可使用链式的调用方式来执行任务,也包括并行任务处理 一个工作任务的执行结果可以作为下一个任务的输入 兼容API 14 以上 可以支持Google play services 支持LiveData 0x01 理论篇——重要的类 WorkManager库中有一些非常重要的类,这些类帮助你构建后台执行的工作任务: Worker:这是一个抽象类,它表示一个工作任务,继承这个类实现doWork()方法,这里就是实现执行任务的主要逻辑。 WorkRequest:表示一个工作任务请求,指定执行哪个Work,它还可以设置任务执行的约束条件...
- 下一篇
iOS 开发之使用 Facebook POP
需要打造游戏级别的动画效果? Facebook 开源的 POP 是一个在 iOS 与 OS X 上通用的极具扩展性的动画引擎,它在基本的静态动画的基础上增加的弹簧动画与衰减动画。 POP 通过 CADisplayLink 将 APP 的重绘速度提高到跟屏幕刷新频率一致的 60 FPS !从而提供游戏级别的动画引擎,由此我们可以创造出更真实、更具物理性、更流畅的交互动画! 没有对比就没有伤害,感兴趣的的同学可以看一下 纯洁的小袋子 的“ Core Animation & Facebook's POP 对比” 。 POP 的架构 POP 目前由四部分组成: Animations Engine Utility WebCore Facebook POP WebCore 里包含了一些从 Apple 的开源的网页渲染引擎里拿出的源文件,与 Utility 里的组件一并,提供了 POP 的各项复杂计算的基本支持。 由此通过 Engine、Utility、WebCore 三个基石,打造了Animations。 POP 提供的动画类 POPAnimation(动画的抽象基类) POPBasicA...
相关文章
文章评论
共有0条评论来说两句吧...