val request = PeriodicWorkRequestBuilder<FooWorker>(1, TimeUnit.DAYS).build()
WorkManager.getInstance().enqueueUniquePeriodicWork(
"FOO",
ExistingPeriodicWorkPolicy.REPLACE,
request
)
上面的代码onCreate
Application
运行,以确保请求排队。但是,这将导致每次用户启动应用程序时FooWorker
都会运行的问题,因为ExistingPeriodicWorkPolicy.REPLACE
取消以前的工作并将新工作排队,从而导致它立即运行。
如果我们更改为ExistingPeriodicWorkPolicy.KEEP
,即使期间或工人发生变化,我们也无法替换工作。
有没有办法在当前请求运行后替换请求?
例如,源请求每天运行 1 次,新请求每小时运行 1 次。运行下一个源请求后,将其替换为新请求。
没有办法以干净的方式通过定期工作完全完成您想要的操作。
但是,绝对没有必要使用定期工作本身。通过在doWork
方法结束时,在返回Result.SUCCESS
之前安排下一个工作请求,可以轻松实现相同的结构:
fun doWork(): Result {
reallyDoWork()
// Now schedule the next "periodic" work
val request = OneTimeWorkRequestBuilder<FooWorker>().build()
WorkManager.getInstance().enqueueUniqueWork(
"FOO",
ExistingWorkPolicy.REPLACE,
request
)
return Result.SUCCESS
}
通过此设置,您的Application
onCreate()
可以安全地使用ExistingWorkPolicy.KEEP
来避免重新安排工作,如果您已经有一个 WorkRequest 排队,并且当排队的工作触发时,下一个 WorkRequest 将使用相应的新时间段排队。
看起来有一种方法现在可以用enqueueUniquePeriodicWork替换周期性工作。
val request = PeriodicWorkRequest.Builder(FooWorker::class.java, 1, TimeUnit.DAYS).build()
WorkManager.getInstance(appContext)
.enqueueUniquePeriodicWork(WORK_TAG, ExistingPeriodicWorkPolicy.REPLACE, request)
确保您通过ExistingPeriodicWorkPolicy
而不是ExistingWorkPolicy
如果您想使用ExistingPeriodicWorkPolicy.KEEP
并且仅在要更改重复间隔时才更新 PeriodicWorkRequest,则 WorkManager 没有解决方案,但您可以在共享首选项中保存间隔并检查间隔是否已更改。并在此基础上使用ExistingPeriodicWorkPolicy.KEEP
或ExistingPeriodicWorkPolicy.REPLACE
public static void enqueue(Context context) {
Log.d(TAG, "enqueue()");
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
int repeatInterval = sharedPreferences.getInt("REPEAT_INTERVAL_HOURS", 0);
PeriodicWorkRequest periodicWorkRequest = new PeriodicWorkRequest
.Builder(FooWorker.class, REPEAT_INTERVAL_HOURS, TimeUnit.HOURS)
.build();
ExistingPeriodicWorkPolicy policy = repeatInterval == REPEAT_INTERVAL_HOURS ? ExistingPeriodicWorkPolicy.KEEP : ExistingPeriodicWorkPolicy.REPLACE;
sharedPreferences.edit().putInt("REPEAT_INTERVAL_HOURS", REPEAT_INTERVAL_HOURS).apply();
WorkManager.getInstance(context).enqueueUniquePeriodicWork("fileRemove", policy, periodicWorkRequest);
}