未使用 ExistingPeriodicWorkPolicy.REPLACE 替换 WorkManager

WorkManager not being replaced using ExistingPeriodicWorkPolicy.REPLACE

调用 ExistingPeriodicWorkPolicy.REPLACE 只是启动另一个 workManager 它不会替换另一个,多个 workManager 在触发时 运行 不会被替换

val constraints = Constraints.Builder()
        .setRequiredNetworkType(NetworkType.CONNECTED)
        .build()

    val workRequest = PeriodicWorkRequestBuilder<SongsWorker>(1, TimeUnit.DAYS)
            .addTag(TAG)
            .setConstraints(constraints)
            .build()

    WorkManager.getInstance(mContext).enqueueUniquePeriodicWork(
        TAG, ExistingPeriodicWorkPolicy.REPLACE, workRequest)

日志表明工作管理器至少要求取消,但执行仍在继续

I/WM-WorkerWrapper: Work [ id=6ed5487e-5d7b-4db5-a4c5-c22c562567e5, tags={ 
workerManagers.songs.SongsWorkerManager$SongsWorker } ] was cancelled
java.util.concurrent.CancellationException: Task was cancelled.
    at androidx.work.impl.utils.futures.AbstractFuture.cancellationExceptionWithCause(AbstractFuture.java:1184)
    at androidx.work.impl.utils.futures.AbstractFuture.getDoneValue(AbstractFuture.java:514)
    at androidx.work.impl.utils.futures.AbstractFuture.get(AbstractFuture.java:475)
    at androidx.work.impl.WorkerWrapper.run(WorkerWrapper.java:300)
    at androidx.work.impl.utils.SerialExecutor$Task.run(SerialExecutor.java:91)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
    at java.lang.Thread.run(Thread.java:923)

我给工作管理器附加了一个监听器,日志是

2021-04-30 20:40:54.318 17868-17868 Fragment: ID = 9f8b3165-fc75-4f9a-ba39-41c2dc6a17b3
2021-04-30 20:40:54.408 17868-17868 Fragment: ID = 9f8b3165-fc75-4f9a-ba39-41c2dc6a17b3
2021-04-30 20:40:54.427 17868-17868 Fragment: ID = 9f8b3165-fc75-4f9a-ba39-41c2dc6a17b3

听众是:

val instance = WorkManager.getInstance(requireContext())
  instance.getWorkInfosForUniqueWorkLiveData(SongsWorkerManager.TAG)
        .observe(viewLifecycleOwner) { workInfo ->
            workInfo.forEach {
                Log.d(TAG, "ID = ${it.id}")
            }
        }

触发工作管理器3次后,3个相同的工作管理器被运行而不是被替换。

以上日志并不能证明旧工人没有被取消。可以添加如下观察者通过WorkInfo

查看所有worker的当前状态
WorkManager.getInstance(context).getWorkInfosByTagLiveData(TAG)
            .observe(lifecycleOwner, { workInfo ->
                workInfo.forEach { 
                    println("Worker Info -> $it")
                }
            })

如果其他人在使用 ExistingPeriodicWorkPolicy.REPLACE 停止工作管理器时遇到问题,请致电

if (isStopped) return Result.success()

在 doWork() 内部,您将获得预期的行为。

感谢

""一种方法是在您的 doWork 方法中进行一些检查,通过调用 isStopped() 来检查 worker 是否已被取消。如果 isStopped 为真,return 从带有结果的方法开始,而不是继续其余的工作。""