我正在构建一个功能,允许商家设置他们的业务时间表。这样的功能将根据商家在一周中的每一天设置的时间自动地将变量open
改变为true
和false
。因此,总共将有14个可能的不同时间。
我正在尝试构建一个重复的后台任务,使用WorkManager,新的Android架构组件库来完成这样的任务。
val scheduleStartWork = PeriodicWorkRequest.Builder(ScheduleWorker::class.java, 7, TimeUnit.DAYS)
.setInputData(Data.Builder().putBoolean("isStart", true).build())
.setScheduleRequestedAt(diff_time, TimeUnit.MILLISECONDS)
.addTag(weekdays[index])
.build()
不过,它给了我以下APILibraryException错误:
Builder.setScheduleRequestedAt只能从同一库组中调用
我的问题:
1( 如果我想将调度延迟diff_time
,那么调用setScheduleRequestedAt
的方法正确吗?
2( 如果是,我该如何解决这个问题?
PS:diff_time
是与用户设置的每天相应小时之间的差值,以毫秒为单位。示例:周一至周五=08:00,周六至周日=10:00。
更新
由于WorkManager v2.1-alpha02,现在可以为PeriodicWorkRequest
添加初始延迟。现在你的电话变成了简单的:
val scheduleStartWork = PeriodicWorkRequest.Builder(ScheduleWorker::class.java, 7, TimeUnit.DAYS)
.setInputData(Data.Builder().putBoolean("isStart", true).build())
.setInitialDelay(diff_time, TimeUnit.MILLISECONDS)
.addTag(weekdays[index])
.build()
注意由于父类WorkRequest
中引入了setInitialDelay
,因此OneTimeWorkRequest#setInitialDelay()
方法引入了从v2.0到v2.1的二进制更改。这意味着要使用新库,您需要在从v2.0升级时重新编译项目。
遵循原始答案
使用WorkManager无法延迟定期任务的首次运行。
您的最佳选择是使用具有您想要的延迟的OneTimeWorker,从那里您可以将您的定期工作人员与您想要的周期进行排队。
WorkManager的问题跟踪器上有一个功能请求,其中包含对此解决方法的解释,您可以将其用作参考。
注意:由于最小间隔的工作方式,您无法建立在重复时间执行的定期工作请求,例如每天凌晨4:00。您可以指定24小时的重复间隔,但这可以使工作人员在第一天凌晨4:05、第二天上午6:00、第三天上午6:10执行,依此类推。如果你需要每天在同一时间执行一个工作者,你最好的选择是使用具有初始延迟的OneTimeWorkRequest
:
OneTimeWorkRequest save = new OneTimeWorkRequest
.Builder(SaveImageToFileWorker.class)
.setConstraints(constraints)
.setInitialDelay(24, TimeUnit.HOURS)
.addTag(TAG_OUTPUT)
.build();
当工作程序完成后,您可以使用Delay重新安排它,以便在正确的时间解雇它(执行工作程序的确切时间取决于创建工作请求时使用的约束(。
您需要将工作管理器库版本更新为2.1.0-alpha03。在版本中,WorkManager提供了在任务中添加初始延迟的功能。
然后您需要使用方法setInitialDelay((。以下是实现使用相同的方式来实现特定时间触发的工作:
long initialDelayInSeconds = (futureSpecificTime - System.currentTimeInMills()) / 1000;
PeriodicWorkRequest workRequest =
new PeriodicWorkRequest.Builder(WorkerClass.class, interval, TimeUnit.SECONDS)
.setConstraints(workRequestConstraints)
.setInputData(inputData)
.addTag(TAG_TASK)
.setInitialDelay(initialDelayInSeconds, TimeUnit.SECONDS)
.build();
在新版工作管理器(2019年5月16日发布的2.1.0-alpha02版本(中,PeriodicWorkRequest现在支持初始延迟。您可以在PeriodicWorkRequest.Builder上使用setInitialDelay方法来设置初始延迟。
PeriodicWorkRequest workRequest = new PeriodicWorkRequest.Builder(
WorkerReminderPeriodic.class,
24,
TimeUnit.HOURS,
PeriodicWorkRequest.MIN_PERIODIC_FLEX_MILLIS,
TimeUnit.MILLISECONDS)
.setInitialDelay(1, TimeUnit.HOURS)
.addTag("send_reminder_periodic")
.build();
WorkManager.getInstance()
.enqueueUniquePeriodicWork("send_reminder_periodic", ExistingPeriodicWorkPolicy.REPLACE, workRequest);