在哪里排队执行唯一重复周期性工作是最佳位置?

4
我希望每天将数据库与服务器数据同步一次,最好的位置来排队工作是什么?以便它只运行一次每天? WorkManager似乎不关心下一个enqueue调用是否在repeatInterval内。如果我将排队工作放在Application类中,并且如果该工作完成,如果我关闭并重新打开应用程序,WorkManager将再次运行它。
这是否意味着我始终需要在调用WorkManager.enqueue()之前检查工作是否已经排队?
val workInfo = workManager.getWorkInfosForUniqueWork("UNIQUE_WORK_NAME").get()?.getOrNull(0)
if (workInfo?.state == WorkInfo.State.ENQUEUED) {
    // do nothing
    return
}

workManager.enqueueUniquePeriodicWork(
                "UNIQUE_WORK_NAME",
                ExistingPeriodicWorkPolicy.KEEP,
                PeriodicWorkRequestBuilder<SyncDbWorker>(
                        1,
                        TimeUnit.DAYS
                )
                .setConstraints(constraints)
                .build())

更新:

我忘记提到一件事,那就是在我的Worker内部,我始终会返回Result.success()。因此,如果工作出现故障,WorkManager将在下一个迭代中重试它。


根据使用情况而定,如果您有一个单一的活动应用程序,请在那里使用它,否则只在您需要的活动中使用它。 - coroutineDispatcher
@StavroXhardha 问题在于它不属于任何活动,这项工作只需每天完成一次(点火并忘记)。 - madim
1个回答

3
使用enqueueUniquePeriodicWork()时,您无需检查工作是否已经排队。使用ExistingPeriodicWorkPolicy中的Keep,将保证只有在没有其他具有相同uniqueWorkName的工作已经计划的情况下才会排队工作。
话虽如此,您可以将唯一的工作排队的通常位置是应用程序的onCreate()回调。这将确保作业已计划。
请记住,PeriodicWorkRequest可能会随着时间的推移而滑动,如文档所述。我在上个月的演讲(大约在24:25左右)中提到了这一点,并提出了一种可能的解决方法。支持DailyWorkers预计将在接下来的alpha版本中的v2.1.x中实现。

WorkManager.enqueueUniquePeriodicWork() 似乎不是按照那种方式工作的。有时候,当我杀死并重新启动应用程序时,它会忽略间隔时间,至少在我的模拟器上是这样。这是一个错误吗? - madim
1
我刚刚找到了解决我的问题的答案:https://issuetracker.google.com/issues/129654588#comment2 - madim
1
目前WorkManager中没有新增功能来满足此需求。WorkManager不支持精确定时和相对延迟。要实现真正的“每日工人”,我们还需要考虑电话时区的变化,这不是我们正在处理的事情。如果您认为这对库很重要,请提交功能请求:https://issuetracker.google.com/issues/new?component=409906&template=1094197 - pfmaggi
什么是 DailyWorkers - IgorGanapolsky
我使用术语“DailyWorker”来表示一个工作程序,它每天都在相同的时间执行一次(例如,每天早上6:00执行的工作程序)。 - pfmaggi
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接