用于在后台运行日常任务的Android WorkManager api

时间:2018-05-18 16:35:23

标签: android android-jobscheduler android-jetpack android-workmanager

即使应用已关闭,我也需要每天在后台调用一个API。我见过有关WorkManager API的信息。对于我的场景,我尝试了PeriodicWorkRequest,但遗憾的是,它不能达到我预期的结果。我所做的是我在Application类

中使用了这段代码
AtomicText

但是当应用程序第一次打开时,它会重复运行11次,但是在24小时后它没有运行。请任何人帮助我解决。

6 个答案:

答案 0 :(得分:20)

如果要确保不会多次创建PeriodicWorkRequest,可以使用WorkManager.enqueueUniquePeriodicWork方法来安排工作人员:

  

此方法使您可以排队一个唯一命名的PeriodicWorkRequest,其中一次只能激活一个具有特定名称的PeriodicWorkRequest。例如,您可能只希望激活一个同步操作。如果有一个未决,您可以选择让它运行或用新工作替换它。


例如:

PeriodicWorkRequest.Builder myWorkBuilder =
            new PeriodicWorkRequest.Builder(MyWorker.class, 24, TimeUnit.HOURS);

PeriodicWorkRequest myWork = myWorkBuilder.build();
WorkManager.getInstance()
    .enqueueUniquePeriodicWork("jobTag", ExistingPeriodicWorkPolicy.KEEP, myWork);

答案 1 :(得分:8)

我认为有三个问题。

1)每次enqueue myWork WorkManager个实例时,您都会创建一个新的定期工作。

尝试一下,doWork()的{​​{1}}方法中的逻辑第一次运行,第二次运行两次。您最有可能向Work Manager添加了11个作品,这就是它最后一次检查时运行11次的原因。如果您创建新作品并将其添加到工作管理器,则MyWorker.class运行的次数会增加。

与Job Scheduler类似,您必须先检查Work是否存在,然后再将其添加到Work Manager中。

示例代码:

myWork

在上面的示例中,我使用唯一标记final WorkManager workManager = WorkManager.getInstance(); final LiveData<List<WorkStatus>> statusesByTag = workManager .getStatusesByTag(TAG_PERIODIC_WORK_REQUEST); statusesByTag.observe(this, workStatuses -> { if (workStatuses == null || workStatuses.size() == 0) { Log.d(TAG, "Queuing the Periodic Work"); // Create a periodic request final PeriodicWorkRequest periodicWorkRequest = new PeriodicWorkRequest.Builder(SyncWorker.class, 30, TimeUnit.MINUTES) .addTag(TAG_PERIODIC_WORK_REQUEST) .build(); // Queue the work workManager.enqueue(periodicWorkRequest); } else { Log.d(TAG, "Work Status Size: " + workStatuses.size()); for (int i = 0; i < workStatuses.size(); i++) { Log.d(TAG, "Work Status Id: " + workStatuses.get(i).getId()); Log.d(TAG, "Work Status State: " + workStatuses.get(i).getState()); } Log.d(TAG, "Periodic Work already exists"); } }); 来识别我的定期作品,并在创建之前检查它是否存在。

2)当应用程序被杀时,您的工作可能无法运行。

品牌是什么,您正在测试?是小米吗?您是否已在多个其他品牌上进行过测试,最终得到了相同的结果?

是否处于打盹模式?当你设置24小时时,你如何验证工作没有运行?

Work Manager提供向后兼容性,但您仍需要处理特定于设备的逻辑。在小米设备上,类似于Job Scheduler(或Firebase作业调度程序或警报),定期工作会在应用程序被终止时停止。

3)我认为TAG_PERIODIC_WORK_REQUEST提供的PeriodicWorkRequest是错误的。

自上周开始以来,我一直在多台设备上测试它。当应用程序第一次启动时,我创建了一个工作,并且没有打开它三天。它第一次运行一次,第二次同步被触发时两次运行,两次之间,它增加到13次,减少到1次,4次等等。

在另一个测试中,我在第一次安装期间使用以下代码创建了一个工作,并从第二次安装中删除了代码。在此测试期间,即使工作成功完成,每次都会进行工作,应用程序在被杀后也会打开。

WorkManager

我明白,因为它仍处于alpha状态。我不认为你应该在生产中使用它。

答案 2 :(得分:2)

如果您向PeriodicWorkRequestBuilder添加标记,然后在排除定期请求之前调用WorkManager.getInstance().cancelAllWorkByTag(REQUEST_TAG),则会阻止欺诈行为发生:

Android Workmanager PeriodicWorkRequest is not unique

答案 3 :(得分:1)

alpha03开始,您可以安排唯一的定期工作: https://developer.android.com/jetpack/docs/release-notes

  

WorkManager.enqueueUniquePeriodicWork(String uniqueWorkName,   现有PeriodicWorkPolicy现有PeriodicWorkPolicy,   PeriodicWorkRequestperiodWork)允许您排队唯一   PeriodicWorkRequest

因此,现在轻松实现您想要的目标。

答案 4 :(得分:0)

alpha 01中存在以下问题:

  

修复了导致Worker在Application.onCreate()上重新安排的问题。

使用最新版本的WorkManager,即1.0.0-alpha02。查看release notes了解详情

答案 5 :(得分:0)

使用WorkManager版本 1.0.0-alpha04 。您可以查看发行说明here

此外,请参考此PeriodicWorkRequest GitHub demo,该{@ 3}在维护窗口期间每天(每24小时)更新一次日计数器。无论应用程序是打开还是关闭,它都会执行doWork()方法。

WorkManager仍处于Alpha模式,因此一旦所有设备发布最终版本,它将完全适用于所有设备。