使用 WorkManager 的定期日常工作请求

Posted

技术标签:

【中文标题】使用 WorkManager 的定期日常工作请求【英文标题】:Periodic daily work requests using WorkManager 【发布时间】:2018-10-25 16:37:24 【问题描述】:

如何正确使用来自 android Jetpack 的新 WorkManager 来安排每天一次的定期工作,该工作应该每天执行一些操作,并且恰好一次?

这个想法是使用WorkManager检查具有给定标签的工作是否已经存在,否则开始一个新的定期工作。

我尝试过使用下一种方法:

public static final String CALL_INFO_WORKER = "Call worker";

...

WorkManager workManager = WorkManager.getInstance();
List<WorkStatus> value = workManager.getStatusesByTag(CALL_INFO_WORKER).getValue();
if (value == null) 
    WorkRequest callDataRequest = new PeriodicWorkRequest.Builder(CallInfoWorker.class,
                24, TimeUnit.HOURS, 3, TimeUnit.HOURS)
                .addTag(CALL_INFO_WORKER)
                .build();
    workManager.enqueue(callDataRequest);

但是value 始终为空,即使我在WorkerdoWork() 方法中放置了一个断点(所以它肯定是在进行中)并从另一个线程检查工作状态。

【问题讨论】:

【参考方案1】:

您现在可以使用enqueueUniquePeriodicWork 方法。它是在 WorkManager 的 1.0.0-alpha03 版本中添加的。

【讨论】:

@atasoyh 你有什么我可以读到的错误报告吗? @stefana github.com/googlecodelabs/android-workmanager/issues/28 alpha10 已发布。 这在奥利奥和棒棒糖上不起作用,这里有什么帮助吗?【参考方案2】:

您正在寻找enqueueUniquePeriodicWork

此方法允许您将唯一命名的队列 PeriodicWorkRequest,其中只有一个 PeriodicWorkRequest 的 特定名称可以同时处于活动状态。例如,您只能 希望一个同步操作处于活动状态。如果有一个待处理,您可以 选择让它运行或用你的新作品替换它。

示例代码

public static final String TAG_MY_WORK = "mywork";

public static void scheduleWork(String tag) 
    PeriodicWorkRequest.Builder photoCheckBuilder =
            new PeriodicWorkRequest.Builder(WorkManagerService.class, 1, TimeUnit.DAYS);
    PeriodicWorkRequest request = photoCheckBuilder.build();
    WorkManager.getInstance().enqueueUniquePeriodicWork(tag, ExistingPeriodicWorkPolicy.KEEP , request);

你会得到两种类型的ExistingPeriodicWorkPolicy

保持

如果存在具有相同唯一名称的现有待处理工作,请执行 什么都没有。

替换

如果存在具有相同唯一名称的现有待处理工作,请取消 并删除它。

【讨论】:

谢谢,当被问到这个问题时,这不是 API 的一部分。当它出现时,给出了解决的答案。 我在上面定期尝试过。它只能一次正常工作,当它改变下一个日期时,它不会触发。尝试使用 2.3.0-beta02【参考方案3】:

最终,我明白,问题在于LiveData 的使用方式。因为没有观察者,所以里面没有价值。

只使用PeriodicWork 的问题在于它不能确保您想做的工作的唯一性。换句话说,有可能有许多作品同时激活,发射次数超过您的需要。

【讨论】:

我想每天显示一次通知,我尝试过定期工作。似乎它不起作用。 PeriodicWorkRequest.Builder myWorkBuilder = new PeriodicWorkRequest.Builder(MyWorker.class, 24, TimeUnit.HOURS); .它只显示一天后它没有显示,如果应用程序在后台运行,它将正确显示。我在应用程序类中调用了 workrequest 我无法在 24 小时内检查它,但我的 15 分钟测试进展顺利,即使在手机重启后也是如此。 你能分享你的代码 15 分钟吗...我试过这个 PeriodicWorkRequest.Builder myWorkBuilder = new PeriodicWorkRequest.Builder(MyWorker.class, 5, TimeUnit.SECONDS,5,TimeUnit.SECONDS);用于测试...每 5 秒运行一次,第一次和第二次时间间隔是什么意思? PeriodicWorkRequest.Builder myWorkBuilder = new PeriodicWorkRequest.Builder(MyWorker.class, 5, TimeUnit.SECONDS,5,TimeUnit.SECONDS);此代码连续运行前 5 秒,之后它没有运行 @LavanyaVelusamy 定期请求的理想最短时间是 15 分钟(在 IO 18 中提到过)。

以上是关于使用 WorkManager 的定期日常工作请求的主要内容,如果未能解决你的问题,请参考以下文章

如何让 Flutter Workmanager 插件和 Location 插件一起工作

Oppo Realme 1 Job Scheduler 定期工作的最小间隔为 1 小时

用于位置跟踪的前台服务与 WorkManager

Android WorkManager - 我可以将输入数据传递给定期运行的 Worker 吗?

WorkManager 在应用关闭后停止调度周期性 Worker

Workmanager 中唯一的 OneTimeWorkRequest