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

Periodic daily work requests using WorkManager

如何正确使用来自 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 始终为 null,即使我在 WorkerdoWork() 方法中放置了一个断点(所以它肯定在进行中)并检查工作状态来自另一个线程。

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

仅使用 PeriodicWork 的问题在于它不能确保您要完成的工作的唯一性。换句话说,有可能有许多同时激活的作品比您需要的次数更多。

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

您正在寻找enqueueUniquePeriodicWork

This method allows you to enqueue a uniquely-named PeriodicWorkRequest, where only one PeriodicWorkRequest of a particular name can be active at a time. For example, you may only want one sync operation to be active. If there is one pending, you can choose to let it run or replace it with your new work.

示例代码

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

KEEP

If there is existing pending work with the same unique name, do nothing.

REPLACE

If there is existing pending work with the same unique name, cancel and delete it.