当前位置:网站首页>WorkManager的学习二
WorkManager的学习二
2022-07-05 09:49:00 【Mr_Tony】
一、前言
Work
在运行期间有几种状态。在运行过程中, State
也随之改变。当任务开始是,状态是 ENQUEUED
。运行时转变为RUNNING
,运行结束时会变成 SUCCEEDED
、FAILED
。如果是重试的话,状态会重新回到ENQUEUED
。如果取消工作,状态就会变成 CANCELLED
。
SUCCEEDED
、FAILED
和 CANCELLED
均表示此工作的终止状态。如果您的工作处于上述任何状态,WorkInfo.State.isFinished()
都将返回 true。
以下是任务执行的流程图
上面是一个一次性任务的执行流程。如果是定时任务,那么就不会有SUCCEEDED
、FAILED
状态。以下是定时任务的流程图。
二、唯一工作
一般来说启动工作可以使用以下方式
WorkManager
.getInstance(this)
.enqueue(uploadWorkRequest)
不过如果我们无意中写了两次该代码,那么任务就会执行两次(虽说这个是不应该出现的)。为了避免这个问题,官方对一次性任务和定时任务分别提供了保证其唯一执行的方式。
这两种方法都接受 3 个参数:
- uniqueWorkName - 用于唯一标识工作请求的
String
。 - existingWorkPolicy - 此
enum
可告知 WorkManager:如果已有使用该名称且尚未完成的唯一工作链,应执行什么操作。如需了解详情,请参阅冲突解决政策。 - work - 要调度的
WorkRequest
。
参考代码如下:
val sendLogsWorkRequest =
PeriodicWorkRequestBuilder<SendLogsWorker>(24, TimeUnit.HOURS)
.setConstraints(Constraints.Builder()
.setRequiresCharging(true)
.build()
)
.build()
WorkManager.getInstance(this).enqueueUniquePeriodicWork(
"sendLogs",
ExistingPeriodicWorkPolicy.KEEP,
sendLogsWorkRequest
)
三、冲突策略
以下参考官网
调度唯一工作时,您必须告知 WorkManager 在发生冲突时要执行的操作。您可以通过在将工作加入队列时传递一个枚举来实现此目的。
对于一次性工作,您需要提供一个
ExistingWorkPolicy
,它支持用于处理冲突的 4 个选项。
REPLACE
:用新工作替换现有工作。此选项将取消现有工作。KEEP
:保留现有工作,并忽略新工作。APPEND
:将新工作附加到现有工作的末尾。此政策将导致您的新工作链接到现有工作,在现有工作完成后运行。现有工作将成为新工作的先决条件。如果现有工作变为
CANCELLED
或FAILED
状态,新工作也会变为CANCELLED
或FAILED
。如果您希望无论现有工作的状态如何都运行新工作,请改用APPEND_OR_REPLACE
。
APPEND_OR_REPLACE
函数类似于APPEND
,不过它并不依赖于先决条件工作状态。即使现有工作变为CANCELLED
或FAILED
状态,新工作仍会运行。对于定期工作,您需要提供一个
ExistingPeriodicWorkPolicy
,它支持REPLACE
和KEEP
这两个选项。这些选项的功能与其对应的 ExistingWorkPolicy 功能相同。
四、观察工作的状态
当工作启动后,可以通过以下方式获取相应的工作信息。
// by id
workManager.getWorkInfoById(syncWorker.id) // ListenableFuture<WorkInfo>
// by name
workManager.getWorkInfosForUniqueWork("sync") // ListenableFuture<List<WorkInfo>>
// by tag
workManager.getWorkInfosByTag("syncTag") // ListenableFuture<List<WorkInfo>>
上面三种获取的方式对应的赋值方式如下:
// by id
val uploadWorkRequest: OneTimeWorkRequest = OneTimeWorkRequest.from(WorkTest::class.java)//简单方式
val workerId = uploadWorkRequest.id
//by name
WorkManager
.getInstance(this)
.enqueueUniqueWork("workName",
ExistingWorkPolicy.KEEP,
uploadWorkRequest)
//by tag
val uploadWorkRequest: WorkRequest = //复杂的构建器方式
OneTimeWorkRequestBuilder<WorkTest>()
.addTag("first")
.build()
该查询会返回
WorkInfo
对象的ListenableFuture
,该值包含工作的id
、其标记、其当前的State
以及通过Result.success(outputData)
设置的任何输出数据。利用每个方法的
LiveData
变种,您可以通过注册监听器来观察WorkInfo
的变化(需要注意的是调用的函数名字是getWorkInfoByIdLiveData而不是getWorkInfoById())。例如,如果您想要在某项工作成功完成后向用户显示消息,您可以进行如下设置:workManager.getWorkInfoByIdLiveData(syncWorker.id) .observe(viewLifecycleOwner) { workInfo -> if(workInfo?.state == WorkInfo.State.SUCCEEDED) { Snackbar.make(requireView(), R.string.work_completed, Snackbar.LENGTH_SHORT) .show() } }
五、复杂的查询
WorkManager 2.4.0 及更高版本支持使用
WorkQuery
对象对已加入队列的作业进行复杂查询。WorkQuery 支持按工作的标记、状态和唯一工作名称的组合进行查询。以下示例说明了如何查找带有“syncTag”标记、处于
FAILED
或CANCELLED
状态,且唯一工作名称为“preProcess”或“sync”的所有工作。val workQuery = WorkQuery.Builder .fromTags(listOf("syncTag")) .addStates(listOf(WorkInfo.State.FAILED, WorkInfo.State.CANCELLED)) .addUniqueWorkNames(listOf("preProcess", "sync")) .build() val workInfos: ListenableFuture<List<WorkInfo>> = workManager.getWorkInfos(workQuery)
WorkQuery
中的每个组件(标记、状态或名称)与其他组件都是AND
逻辑关系。组件中的每个值都是OR
逻辑关系。例如:(name1 OR name2 OR ...) AND (tag1 OR tag2 OR ...) AND (state1 OR state2 OR ...)
。
WorkQuery
也适用于等效的 LiveData 方法getWorkInfosLiveData()
。
六、取消和停止工作
任务有时候需要取消,可以使用以下方式
// by id
workManager.cancelWorkById(syncWorker.id)
// by name
workManager.cancelUniqueWork("sync")
// by tag
workManager.cancelAllWorkByTag("syncTag")
WorkManager 会在后台检查工作的
State
。如果工作已经完成,系统不会执行任何操作。否则,工作的状态会更改为CANCELLED
,之后就不会运行这个工作。任何依赖于此工作的WorkRequest
作业也将变为CANCELLED
。目前,
RUNNING
可收到对ListenableWorker.onStopped()
的调用。如需执行任何清理操作,请替换此方法。如需了解详情,请参阅停止正在运行的工作器。
所以任务停止后,可以在重写的onStopped()
函数中处理收尾工作。也可以通过 ListenableWorker.isStopped()
来见擦汗任务是否停止,示例如下:
class WorkTest(val appContext: Context, workerParams: WorkerParameters): Worker(appContext, workerParams) {
override fun doWork(): Result {
if(isStopped){
return Result.success()
}
return Result.success()
}
}
七、参考链接
边栏推荐
- 历史上的今天:第一本电子书问世;磁条卡的发明者出生;掌上电脑先驱诞生...
- 天龙八部TLBB系列 - 关于技能冷却和攻击范围数量的问题
- Design and Simulation of fuzzy PID control system for liquid level of double tank (matlab/simulink)
- [论文阅读] CKAN: Collaborative Knowledge-aware Atentive Network for Recommender Systems
- (1) Complete the new construction of station in Niagara vykon N4 supervisor 4.8 software
- 【 conseils 】 obtenir les valeurs des axes X et y de la fonction cdfplot dans MATLAB
- 自动化规范检查软件如何发展而来?
- mongoDB副本集
- 天龙八部TLBB系列 - 单体技能群伤
- Kotlin Compose 与原生 嵌套使用
猜你喜欢
Meitu lost 300 million yuan in currency speculation for half a year. Huawei was exposed to expand its enrollment in Russia. Alphago's peers have made another breakthrough in chess. Today, more big new
能源势动:电力行业的碳中和该如何实现?
mysql80服务不启动
Wechat applet - simple diet recommendation (4)
The king of pirated Dall · e? 50000 images per day, crowded hugging face server, and openai ordered to change its name
Energy momentum: how to achieve carbon neutralization in the power industry?
剪掉ImageNet 20%数据量,模型性能不下降!Meta斯坦福等提出新方法,用知识蒸馏给数据集瘦身...
让AI替企业做复杂决策真的靠谱吗?参与直播,斯坦福博士来分享他的选择|量子位·视点...
美图炒币半年亏了3个亿,华为被曝在俄罗斯扩招,AlphaGo的同类又刷爆一种棋,今日更多大新闻在此...
(1) Complete the new construction of station in Niagara vykon N4 supervisor 4.8 software
随机推荐
基于单片机步进电机控制器设计(正转反转指示灯挡位)
Unity粒子特效系列-毒液喷射预制体做好了,unitypackage包直接用 -下
ByteDance Interviewer: how to calculate the memory size occupied by a picture
The king of pirated Dall · e? 50000 images per day, crowded hugging face server, and openai ordered to change its name
[system design] index monitoring and alarm system
盗版DALL·E成梗图之王?日产5万张图像,挤爆抱抱脸服务器,OpenAI勒令改名
Kotlin compose multiple item scrolling
IDEA新建sprintboot项目
What is the origin of the domain knowledge network that drives the new idea of manufacturing industry upgrading?
Single chip microcomputer principle and Interface Technology (esp8266/esp32) machine human draft
Usage differences between isempty and isblank
程序员如何活成自己喜欢的模样?
Unity particle special effects series - the poison spray preform is ready, and the unitypackage package is directly used - on
Optimize database queries using the cursor object of SQLite
Glide advanced level
【C语言】动态内存开辟的使用『malloc』
Energy momentum: how to achieve carbon neutralization in the power industry?
《剑来》语句摘录(七)
Using directive in angualr2 to realize that the picture size changes with the window size
Openes version query