如何使用WorkManager更改定期工作请求期而不立即运行?


val request = PeriodicWorkRequestBuilder<FooWorker>(1, TimeUnit.DAYS).build()
WorkManager.getInstance().enqueueUniquePeriodicWork(
"FOO",
ExistingPeriodicWorkPolicy.REPLACE,
request
)

上面的代码onCreateApplication运行,以确保请求排队。但是,这将导致每次用户启动应用程序时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
}

通过此设置,您的ApplicationonCreate()可以安全地使用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.KEEPExistingPeriodicWorkPolicy.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);
}

最新更新