万盛网站建设,湖北省南漳县城乡建设局网站,官方正版浏览器,做网站还是租用服务器一、介绍
通过上一篇文#xff0c;Android Jetpack组件之WorkManager后台任务管理的介绍与使用(一)_蜗牛、Z的博客-CSDN博客
我们可以弄清楚workmanager从接入到使用的基本流程。基本可以满足我们日常。那只是简单的入门。如果遇到更复杂的功能#xff0c;那简单的就无法满…一、介绍
通过上一篇文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) // ListenableFutureWorkInfo// by name
workManager.getWorkInfosForUniqueWork(sync) // ListenableFutureListWorkInfo// by tag
workManager.getWorkInfosByTag(syncTag) // ListenableFutureListWorkInfo 监听器:
利用每个方法的 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 会返回 ListenableFutureVoid更新进度是异步过程因为更新过程涉及将进度信息存储在数据库中。在 Kotlin 中您可以使用 CoroutineWorker 对象的 setProgress() 扩展函数来更新进度信息 class MyCoroutineWorker(appContext: Context,params: WorkerParameters
) : CoroutineWorker(appContext, params) {companion object {const val Progress Progressprivate 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 0map(key,value)map(Progress ,0)
在LiveData的observe(this)中,it.progress是Data对象直接通过map对象去获取 加入队列 val coroutineWorker PeriodicWorkRequestBuilderMyCoroutineWorker(20, TimeUnit.MINUTES).build()WorkManager.getInstance(application).enqueue(coroutineWorker)七、链接work 可以使用 WorkManager 创建工作链并将其加入队列。工作链用于指定多个依存任务并定义这些任务的运行顺序。当您需要以特定顺序运行多个任务时 如需创建工作链您可以使用 WorkManager.beginWith(OneTimeWorkRequest) 或 WorkManager.beginWith(ListOneTimeWorkRequest)这会返回 WorkContinuation 实例。 然后可以使用 WorkContinuation 通过 then(OneTimeWorkRequest) 或 then(ListOneTimeWorkRequest) 添加 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 或 ListOneTimeWorkRequest 中成功完成即返回 Result.success()系统会将下一组依存工作请求加入队列。 如果该重试政策未定义或已用尽或者您以其他方式已达到 OneTimeWorkRequest 返回 Result.failure() 的某种状态该工作请求和所有依存工作请求都会被标记为 FAILED。
OneTimeWorkRequest 被取消时遵循相同的逻辑。任何依存工作请求也会被标记为 CANCELLED并且无法执行其工作。
请注意 如果要向已失败或已取消工作请求的链附加更多工作请求新附加的工作请求也会分别标记为 FAILED 或 CANCELLED。如果您想扩展现有链的工作请参阅 ExistingWorkPolicy 中的 APPEND_OR_REPLACE。 十一、调试 WorkManager
启用日志记录 如需确定工作器未正确运行的原因查看详细的 WorkManager 日志很有帮助。如需启用日志记录功能您需要使用自定义初始化。首先通过创建应用了清单合并规则 remove 的新 WorkManager 提供程序来停用 AndroidManifest.xml 中的默认 WorkManagerInitializer2.6以后用InitializationProvider
引入
providerandroid:nameandroidx.startup.InitializationProviderandroid:authorities${applicationId}.androidx-startuptools:noderemove 现在默认 WorkManager 初始化程序已停用您可以使用按需初始化。为此android.app.Application 类必须提供 androidx.work.Configuration.Provider 的实现。
class MyApplication() : Application(), Configuration.Provider {override fun getWorkManagerConfiguration() Configuration.Builder().setMinimumLoggingLevel(android.util.Log.DEBUG).build()
}Javapublic 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 显示