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



即使应用程序关闭,我也需要在后台每天调用一个API。我见过关于WorkManager API。对于我的方案,我尝试了定期工作请求,但不幸的是,它没有达到我的预期结果。我所做的是在应用程序类中使用此代码

PeriodicWorkRequest.Builder myWorkBuilder =
new PeriodicWorkRequest.Builder(MyWorker.class, 24,
TimeUnit.HOURS);
PeriodicWorkRequest myWork = myWorkBuilder.build();
WorkManager.getInstance().enqueue(myWork);

但是,当应用程序首次打开时,它会重复运行 11 次,而在 24 小时后它不会运行。拜托,任何人,帮我解决。

如果要确保不会多次创建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( 每次enqueuemyWorkWorkManager实例时,您都会创建新的定期工作。

试试吧,MyWorker.classdoWork()方法中的逻辑第一次运行一次,第二次运行两次。您很可能在工作管理器中添加了 11 个作品,这就是为什么它运行了 11 次,最后一次检查。如果您创建新作品并将其添加到工作管理器中,则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");
}
});

在上面的示例中,我使用唯一的标记TAG_PERIODIC_WORK_REQUEST来标识我的定期工作,并在创建之前检查它是否存在。

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

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

是否处于打瞌睡模式?当您设置 24 小时时间时,您如何验证工作是否未运行?

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

3(我只是认为WorkManager提供的PeriodicWorkRequest有问题。

自上周初以来,我一直在多个设备上对其进行测试。我在第一次启动应用程序时创建了一个作品,并且三天没有打开它。它第一次运行一次,触发第二次同步时运行两次,在这两者之间,它增加到 13 次,下降到 1 次,4 次等。

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

final PeriodicWorkRequest periodicWorkRequest =
new PeriodicWorkRequest.Builder(SyncWorker.class, 30, TimeUnit.MINUTES)
.addTag("periodic-work-request")
.build();
// Queue the work
WorkManager.getInstance().enqueue(periodicWorkRequest);

我明白这一点,因为它仍处于 alpha 阶段。我认为你不应该在生产中使用它。

如果向PeriodicWorkRequestBuilder添加一个标签,然后在将定期请求排队之前调用WorkManager.getInstance().cancelAllWorkByTag(REQUEST_TAG),这将防止重复发生:

Android Workmanager PeriodicWorkRequest 不是唯一的

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

WorkManager.enqueueUniquePeriodicWork(String uniqueWorkName, 现有定期工作政策 现有定期工作政策, PeriodicWorkRequest periodicWork(允许您排队一个唯一的 定期工作请求

因此,实现您现在想要的东西非常简单。

alpha 01 中存在以下问题:

修复了导致在 Application.onCreate(( 上重新调度工作线程的问题。

使用最新版本的工作管理器,即 1.0.0-alpha02。查看发行说明以获取更多信息

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

另外,请参阅此 PeriodicWorkRequest GitHub 演示,该演示在维护时段内每天(每 24 小时(更新一次日计数器。它执行 doWork(( 方法,无论应用程序是打开还是关闭。

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

最新更新