Android Jetpack组件之WorkManager后台任务管理的介绍与使用(二)
一、介绍
通过上一篇文,Android Jetpack组件之WorkManager后台任务管理的介绍与使用(一)_蜗牛、Z的博客-CSDN博客
我们可以弄清楚workmanager从接入到使用的基本流程。基本可以满足我们日常。那只是简单的入门。如果遇到更复杂的功能,那简单的就无法满足。
二、管理进阶
单一执行:
WorkManager.getInstance(requireContext()).enqueue(myWork)
唯一:
唯一工作既可用于一次性工作,也可用于定期工作。您可以通过调用以下方法之一创建唯一工作序列,具体取决于您是调度重复工作还是一次性工作
- WorkManager.enqueueUniqueWork()(用于一次性工作)
这个只支持OneTimeWorkRequest
- WorkManager.enqueueUniquePeriodicWork()(用于定期工作)
只支持PeriodicWorkRequest
这两种方法都接受 3 个参数:
- uniqueWorkName - 用于唯一标识工作请求的
String。 - existingWorkPolicy - 此
enum可告知 WorkManager:如果已有使用该名称且尚未完成的唯一工作链,应执行什么操作。如需了解详情,请参阅冲突解决政策。 - work - 要调度的
WorkRequest。
冲突解决政策
对于一次性工作,您需要提供一个 ExistingWorkPolicy,它支持用于处理冲突的 4 个选项。
- REPLACE:用新工作替换现有工作。此选项将取消现有工作。
- KEEP:保留现有工作,并忽略新工作。
- APPEND:将新工作附加到现有工作的末尾。此政策将导致您的新工作链接到现有工作,在现有工作完成后运行。
现有工作将成为新工作的先决条件。如果现有工作变为 CANCELLED 或 FAILED 状态,新工作也会变为 CANCELLED 或 FAILED。如果您希望无论现有工作的状态如何都运行新工作,请改用 APPEND_OR_REPLACE。
- APPEND_OR_REPLACE 函数类似于
APPEND,不过它并不依赖于先决条件工作状态。即使现有工作变为CANCELLED或FAILED状态,新工作仍会运行。
对于定期工作,您需要提供一个 ExistingPeriodicWorkPolicy,它支持 REPLACE 和 KEEP 这两个选项。这些选项的功能与其对应的 ExistingWorkPolicy 功能相同。
三、如何获取worker对象
在将工作加入队列后,您可以随时按其 name、id 或与其关联的 tag 在 WorkManager 中进行查询,以检查其状态
三种:
//by uuid
workManager.getWorkInfoById(syncWorker.id) // ListenableFuture<WorkInfo>// by name
workManager.getWorkInfosForUniqueWork("sync") // ListenableFuture<List<WorkInfo>>// by tag
workManager.getWorkInfosByTag("syncTag") // ListenableFuture<List<WorkInfo>>
监听器:
利用每个方法的 LiveData 变种,您可以通过注册监听器来观察 WorkInfo 的变化
val resultData = WorkManager.getInstance(application).getWorkInfoByIdLiveData(id)resultData.observe(this) {if (it?.state == WorkInfo.State.SUCCEEDED) {//}}
复杂的work查询:WorkQuery
WorkManager 2.4.0 及更高版本支持使用 WorkQuery 对象对已加入队列的作业进行复杂查询。WorkQuery 支持按工作的标记、状态和唯一工作名称的组合进行查询。
val workQuery = WorkQuery.Builder.fromTags(listOf("one1")).addStates(listOf(WorkInfo.State.FAILED, WorkInfo.State.CANCELLED)).addUniqueWorkNames(listOf("preProcess", "sync")).build()val workInfos = WorkManager.getInstance(application).getWorkInfos(workQuery)
解释:
WorkQuery 中的每个组件(标记、状态或名称)与其他组件都是 AND 逻辑关系。组件中的每个值都是 OR 逻辑关系
例如:(name1 OR name2 OR ...) AND (tag1 OR tag2 OR ...) AND (state1 OR state2 OR ...)
四、取消和停止work
// by id
workManager.cancelWorkById(build.id)// by name
workManager.cancelUniqueWork("sync")// by tag
workManager.cancelAllWorkByTag("syncTag")
五、停止正在运行的WORK
正在运行的 Worker 可能会由于以下几种原因而停止运行:
- 您明确要求取消它(例如,通过调用
WorkManager.cancelWorkById(UUID)取消)。 - 如果是唯一工作,您明确地将 ExistingWorkPolicy 为 REPLACE 的新
WorkRequest加入到了队列中。旧的WorkRequest会立即被视为已取消。 - 您的工作约束条件已不再满足。
- 系统出于某种原因指示您的应用停止工作。如果超过 10 分钟的执行期限,可能会发生这种情况。该工作会调度为在稍后重试。
在您的工作器停止后,WorkManager 会立即调用 ListenableWorker.onStopped(),您可以调用 ListenableWorker.isStopped() 方法以检查工作器是否已停止
观察worker的中间进度
WorkManager 为设置和观察工作器的中间进度添加了一流的支持。如果应用在前台运行时,工作器保持运行状态,那么也可以使用返回 WorkInfo 的 LiveData 的 API 向用户显示此信息
只有在 ListenableWorker 运行时才能观察到和更新进度信息。如果尝试在 ListenableWorker 完成执行后在其中设置进度,则将会被忽略。您还可以使用 getWorkInfoBy…() 或 getWorkInfoBy…LiveData() 方法来观察进度信息。这两个方法会返回 WorkInfo 的实例,后者有一个返回 Data 的新 getProgress() 方法
六、更新进度
对于使用 ListenableWorker 或 Worker 的 Java 开发者,setProgressAsync() API 会返回 ListenableFuture<Void>;更新进度是异步过程,因为更新过程涉及将进度信息存储在数据库中。在 Kotlin 中,您可以使用 CoroutineWorker 对象的 setProgress() 扩展函数来更新进度信息
class MyCoroutineWorker(appContext: Context,params: WorkerParameters
) : CoroutineWorker(appContext, params) {companion object {const val Progress = "Progress"private const val delayDuration = 1L}override suspend fun doWork(): Result {val firstUpdate = workDataOf(Progress to 0)val lastUpdate = workDataOf(Progress to 100)setProgress(firstUpdate)delay(delayDuration)setProgress(lastUpdate)return Result.Success.success()}override suspend fun getForegroundInfo(): ForegroundInfo {val id = Random.nextInt(0, Int.MAX_VALUE)return ForegroundInfo(id, getNotion())}private fun getNotion(): Notification {val notification = Notification()return notification;}
}
观察信息:
val liveData =WorkManager.getInstance(application).getWorkInfoByIdLiveData(coroutineWorker.id)liveData.observe(this, Observer { workinfo: WorkInfo? ->if (workinfo != null) {val datta = workinfo.progressval state = workinfo.stateif (datta != null && datta.size() > 0) {}}})
注意:
workDataOf(Progress to 0):
workDataOf是Data类里面的,workDataOf直接返回data对象,有因为这个data的存储是Map,所以Progress to 0=map(key,value)=map(Progress ,0)
在LiveData的observe(this)中,it.progress是Data对象,直接通过map对象去获取
加入队列:
val coroutineWorker= PeriodicWorkRequestBuilder<MyCoroutineWorker>(20, TimeUnit.MINUTES).build()WorkManager.getInstance(application).enqueue(coroutineWorker)
七、链接work
可以使用 WorkManager 创建工作链并将其加入队列。工作链用于指定多个依存任务并定义这些任务的运行顺序。当您需要以特定顺序运行多个任务时
如需创建工作链,您可以使用 WorkManager.beginWith(OneTimeWorkRequest) 或 WorkManager.beginWith(List<OneTimeWorkRequest>),这会返回 WorkContinuation 实例。
然后,可以使用 WorkContinuation 通过 then(OneTimeWorkRequest) 或 then(List<OneTimeWorkRequest>) 添加 OneTimeWorkRequest 依赖实例。每次调用 WorkContinuation.then(...) 都会返回一个新的 WorkContinuation 实例。如果添加了 OneTimeWorkRequest 实例的 List,这些请求可能会并行运行
最后,您可以使用 WorkContinuation.enqueue() 方法对 WorkContinuation 工作链执行 enqueue() 操作
如下:
val work= OneTimeWorkRequest.from(MyWorks::class.java)WorkManager.getInstance(application).beginWith(work);WorkManager.getInstance(application).beginWith(work).then(work).then(work);
这种顺序类似属性动画一样,后面按顺序执行。
八、输入合并器
当您链接 OneTimeWorkRequest 实例时,父级工作请求的输出将作为子级的输入传入。因此,在上面的示例中,plantName1、plantName2 和 plantName3 的输出将作为 cache 请求的输入传入。
WorkManager 提供两种不同类型的 InputMerger:
-
OverwritingInputMerger 会尝试将所有输入中的所有键添加到输出中。如果发生冲突,它会覆盖先前设置的键。
-
ArrayCreatingInputMerger 会尝试合并输入,并在必要时创建数组
OverwritingInputMerger
OverwritingInputMerger 是默认的合并方法。如果合并过程中存在键冲突,键的最新值将覆盖生成的输出数据中的所有先前版本。如果每种植物的输入都有一个与其各自变量名称("plantName1"、"plantName2" 和 "plantName3")匹配的键,传递给 cache 工作器的数据将具有三个键值对。如果存在冲突,那么最后一个工作器将在争用中“取胜”,其值将传递给 cache。
由于工作请求是并行运行的,因此无法保证其运行顺序。在上面的示例中,plantName1 可以保留值 "tulip" 或 "elm",具体取决于最后写入的是哪个值。如果有可能存在键冲突,并且您需要在合并器中保留所有输出数据,那么 ArrayCreatingInputMerger 可能是更好的选择。
ArrayCreatingInputMerger
将每个键与数组配对。如果每个键都是唯一的,您会得到一系列一元数组,如果存在任何键冲突,那么所有对应的值会分组到一个数组中。
久、链接和work状态
要工作成功完成(即,返回 Result.success()),OneTimeWorkRequest 链便会按顺序执行。运行时,工作请求可能会失败或被取消,这会对依存工作请求产生下游影响。
当第一个 OneTimeWorkRequest 被加入工作请求链队列时,所有后续工作请求会被屏蔽,直到第一个工作请求的工作完成为止。

在加入队列且满足所有工作约束后,第一个工作请求开始运行。如果工作在根 OneTimeWorkRequest 或 List<OneTimeWorkRequest> 中成功完成(即返回 Result.success()),系统会将下一组依存工作请求加入队列。

如果该重试政策未定义或已用尽,或者您以其他方式已达到 OneTimeWorkRequest 返回 Result.failure() 的某种状态,该工作请求和所有依存工作请求都会被标记为 FAILED。
OneTimeWorkRequest 被取消时遵循相同的逻辑。任何依存工作请求也会被标记为 CANCELLED,并且无法执行其工作。
请注意:
如果要向已失败或已取消工作请求的链附加更多工作请求,新附加的工作请求也会分别标记为 FAILED 或 CANCELLED。如果您想扩展现有链的工作,请参阅 ExistingWorkPolicy 中的 APPEND_OR_REPLACE。
十一、调试 WorkManager
启用日志记录
如需确定工作器未正确运行的原因,查看详细的 WorkManager 日志很有帮助。如需启用日志记录功能,您需要使用自定义初始化。首先,通过创建应用了清单合并规则 remove 的新 WorkManager 提供程序来停用 AndroidManifest.xml 中的默认 WorkManagerInitializer(2.6以后用InitializationProvider)
引入:
<providerandroid:name="androidx.startup.InitializationProvider"android:authorities="${applicationId}.androidx-startup"tools:node="remove">
现在,默认 WorkManager 初始化程序已停用,您可以使用按需初始化。为此,android.app.Application 类必须提供 androidx.work.Configuration.Provider 的实现。
class MyApplication() : Application(), Configuration.Provider {override fun getWorkManagerConfiguration() =Configuration.Builder().setMinimumLoggingLevel(android.util.Log.DEBUG).build()
}Java:public Configuration getWorkManagerConfiguration() {Configuration.Builder builder= new Configuration.Builder();builder.setMinimumLoggingLevel(android.util.Log.DEBUG);return builder.build();}
定义自定义 WorkManager 配置后,WorkManager 会在您调用 WorkManager.getInstance(Context) 时进行初始化,而不是在应用启动时自动初始化
启用 DEBUG 日志记录后,系统会开始显示更多包含日志标记前缀 WM- 的日志
从 WorkManager 2.4.0 及更高版本请求诊断信息
在应用的调试 build 中,您可以使用以下命令从 WorkManager 2.4.0 及更高版本请求诊断信息:
adb shell am broadcast -a "androidx.work.diagnostics.REQUEST_DIAGNOSTICS" -p "<your_app_package_name>"
这提供了以下方面的信息:
- 在过去 24 小时内完成的工作请求。
- 目前正在运行的工作请求。
- 预定运行的工作请求。
诊断信息如下所示(输出通过 logcat 显示)
相关文章:
Android Jetpack组件之WorkManager后台任务管理的介绍与使用(二)
一、介绍 通过上一篇文,Android Jetpack组件之WorkManager后台任务管理的介绍与使用(一)_蜗牛、Z的博客-CSDN博客 我们可以弄清楚workmanager从接入到使用的基本流程。基本可以满足我们日常。那只是简单的入门。如果遇到更复杂的功能,那简单的就无法满…...
【MySQL】第十七部分 约束
【MySQL】第十七部分 约束 文章目录【MySQL】第十七部分 约束17. 约束17.1 约束的分类17.2 非空约束17.3 唯一性约束17.4 主键约束17.5 自增列约束17.6 外键约束17.7 默认约束17.8 check约束总结17. 约束 约束: 可以在创建表的时候规定约束,也可以在表创建之后添加,约束顾名思…...
java ssm集装箱码头TOS系统调度模块的设计与实现
由于历史和经济体制的原因,国内码头物流企业依然保持大而全的经营模式。企业自己建码头、场地、经营集装箱运输车辆。不过近几年来随着经济改革的进一步深入和竞争的激烈,一些大型的码头物流企业逐步打破以前的经营模式,其中最明显的特征就是…...
MS14-064(OLE远程代码执行漏洞复现)
✅作者简介:CSDN内容合伙人、信息安全专业在校大学生🏆 🔥系列专栏 :内网安全-漏洞复现 📃新人博主 :欢迎点赞收藏关注,会回访! 💬舞台再大,你不上台…...
【C++深陷】之shared_ptr
0. 什么是智能指针 使用new 和delete 手动进行动态内存管理很容易出现内存泄漏等问题。C11为了更安全、更方便的管理动态内存,新的标准库提供了两种智能指针(smart pointer):shared_ptr和unique_ptr,以及一个伴随类we…...
SpringMVC中遇到的错误
SpringMVC中遇到的错误1.web.xml中配置SpringMVC核心类: DispatcherServlet 报错解决方案:添加Tomcat包2. not declaration can be found for element--------‘mvc:annotation-driven‘通配符的匹配很全面, 但无法找到元素 mvc:annotation-driven 的声明解决方案&a…...
姿态估计端到端新方案 | DirectMHP:用于全范围角度2D多人头部姿势估计
前言 现有的头部姿势估计主要集中在具有预先检测到的正面头部的单个人,这依赖于单独训练的面部检测器,不能很好地泛化到完整的视点。在本文中,作者关注全范围 MPHPE 问题,并提出了一个名为 DirectMHP 的直接端到端简单基线&#x…...
jvm学习的核心(五)---垃圾回收算法和常见垃圾回收器
文章目录1.垃圾回收算法**1.1. 标记阶段****1.2. 清除阶段**1.2.1.标记清除算法1.2.2.标记复制算法1.2.3.标记整理算法1.3.引用2.常见的垃圾回收器2.1.Serial回收器2.2.ParNew回收器2.3.Parallel回收器2.4.CMS回收器<font color red>2.5.G1垃圾回收器ZGC回收器ÿ…...
亿级高并发电商项目-- 实战篇 --万达商城项目 二(Zookeeper、Docker、Dubbo-Admin等搭建工作
👏作者简介:大家好,我是小童,Java开发工程师,CSDN博客博主,Java领域新星创作者 📕系列专栏:前端、Java、Java中间件大全、微信小程序、微信支付、若依框架、Spring全家桶 Ǵ…...
【C#基础】 C# 数据类型总结
序号系列文章0【C#基础】初识编程语言C#1【C#基础】C# 程序通用结构总结2【C#基础】C# 程序基础语法解析文章目录前言数据类型一. 值类型(Value types)二. 引用类型(Reference types)三. 指针类型(Pointer types&#…...
格子玻尔兹曼法介绍
1 LBM简介格子玻尔兹曼法(Lattice Boltzmann Method)简称LBM,是一种CFD算法,可求解流动、传热等常见CFD问题。LBM基于格子玻尔兹曼方程(LBE),从介观尺度(mesoscope)描述了…...
活动星投票在时间的河流上造园分组怎么设置如何进行分组报名
“在时间的河流上造园”网络评选投票_免费小程序运行系统_企业有关的投票_微信投票的应用小程序投票活动如何做?很多企业在运营当中,都会通过投票活动来进行推广,从而达到吸粉、增加用户粘度等效果。而此类投票活动,通过小程序就可…...
c#小笔记本-基础
c#基本知识一.基础操作1.打印-writeline,write2.输入-readline,readkey二.变量1.折叠代码-#region,#endregion2.变量类型(在c语言变量类型上新增的)三.常量-const四.转义字符五.显示转换1.括号强转-低精度装高精度2.parse法-作用于字符串3.co…...
DamiCMS SQL注入分析
2023年将会持续于B站、CSDN等各大平台更新,可加入粉丝群与博主交流:838681355,为了老板大G共同努力。 一、入口文件(单入口文件模式) 看一下Index.php文件代码:引入了php_safe.php文件 查看一下php_safe.php防御文件: 对变量e…...
图傅里叶变换的推导和理解
把传统的傅里叶变换以及卷积迁移到Graph上来,核心工作其实就是把拉普拉斯算子的特征函数 e − i ω t e^{-i\omega t} e−iω...
Java八股文(Java面试题)
JDK、JRE、JVM 三者之间的关系?JDK(Java Development Kit):是Java开发工具包,是整个Java的核心,包括了Java运行环境JRE、Java工具和Java基础类库。它能够创建和编译程序。JRE(Java Runtime Envi…...
java ssm idea高校图书借阅管理系统设计2z87z
本论文是以构建高校图书管理系统设计为目标,使用 jsp制作,由前台用户图书借阅、后台管理员图书分类两大部分组成。着重论述了系统设计分析,系统的实现(用户注册模块,用户登录,用户图书借阅模块,…...
电脑重装系统注册表恢复方法
今天讲关于大家的电脑在遇到一些故障的时候,以及电脑用久了之后会卡顿,那么这时候大家一般都会给电脑重装系统。重装系统之后却发现自己电脑里的注册表不见了,重装系统后怎么恢复注册表?小编就带着大家一起学习重装系统注册表恢复到底是怎…...
信道建模(大尺度、小尺度、莱斯衰落、瑞利衰落、莱斯信道、瑞利信道)
一、大尺度衰落与小尺度衰落 大尺度衰落由收发两端的距离决定,功率上建模为: 小尺度衰落由收发两端的环境决定,比如是否有遮挡,场景有室内、室外、平原、山村、城镇等,这些环境影响到收发两端是否有直达链路࿰…...
2022年12月电子学会Python等级考试试卷(四级)答案解析
青少年软件编程(Python)等级考试试卷(四级) 一、单选题(共25题,共50分) 1. 有n个按名称排序的商品,使用对分查找法搜索任何一商品, 最多查找次数为5次,则n的值可能为?&…...
大数据学习栈记——Neo4j的安装与使用
本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...
安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...
解锁数据库简洁之道:FastAPI与SQLModel实战指南
在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...
定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
关键领域软件测试的突围之路:如何破解安全与效率的平衡难题
在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件,这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下,实现高效测试与快速迭代?这一命题正考验着…...
C++.OpenGL (20/64)混合(Blending)
混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...
C语言中提供的第三方库之哈希表实现
一. 简介 前面一篇文章简单学习了C语言中第三方库(uthash库)提供对哈希表的操作,文章如下: C语言中提供的第三方库uthash常用接口-CSDN博客 本文简单学习一下第三方库 uthash库对哈希表的操作。 二. uthash库哈希表操作示例 u…...
C# winform教程(二)----checkbox
一、作用 提供一个用户选择或者不选的状态,这是一个可以多选的控件。 二、属性 其实功能大差不差,除了特殊的几个外,与button基本相同,所有说几个独有的 checkbox属性 名称内容含义appearance控件外观可以变成按钮形状checkali…...
