即使应用已关闭,我也需要每天在后台调用一个API。我见过有关WorkManager API的信息。对于我的场景,我尝试了PeriodicWorkRequest,但遗憾的是,它不能达到我预期的结果。我所做的是我在Application类
中使用了这段代码AtomicText
但是当应用程序第一次打开时,它会重复运行11次,但是在24小时后它没有运行。请任何人帮助我解决。
答案 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)
,则会阻止欺诈行为发生:
答案 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模式,因此一旦所有设备发布最终版本,它将完全适用于所有设备。