如何立即使用 WorkManager 运行 更改周期性工作请求周期?
How to change periodic work request period without it running immediately using WorkManager?
val request = PeriodicWorkRequestBuilder<FooWorker>(1, TimeUnit.DAYS).build()
WorkManager.getInstance().enqueueUniquePeriodicWork(
"FOO",
ExistingPeriodicWorkPolicy.REPLACE,
request
)
上面的代码是 运行 in onCreate
of Application
以确保请求入队。但是,这会导致一个问题,即每次用户启动应用程序时 FooWorker
都会 运行,因为 ExistingPeriodicWorkPolicy.REPLACE
取消以前的工作并将新工作加入队列,这会导致它立即 运行。
如果我们改成ExistingPeriodicWorkPolicy.KEEP
,即使更换工期或工人,我们也无法更换工作。
有没有办法替换当前请求运行ning之后的请求?
例如,原始请求运行每天1次,新请求是每小时1次。下一个原始请求运行后,再替换为新的请求
没有办法以干净的方式通过周期性工作准确地完成您想要的事情。
但是,完全没有必要使用周期性工作本身。通过在 doWork
方法的末尾安排下一个 WorkRequest,就在返回 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没有解决方案,但你可以在sharedPreferences中保存间隔并检查间隔是否被改变。并基于此使用 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);
}
val request = PeriodicWorkRequestBuilder<FooWorker>(1, TimeUnit.DAYS).build()
WorkManager.getInstance().enqueueUniquePeriodicWork(
"FOO",
ExistingPeriodicWorkPolicy.REPLACE,
request
)
上面的代码是 运行 in onCreate
of Application
以确保请求入队。但是,这会导致一个问题,即每次用户启动应用程序时 FooWorker
都会 运行,因为 ExistingPeriodicWorkPolicy.REPLACE
取消以前的工作并将新工作加入队列,这会导致它立即 运行。
如果我们改成ExistingPeriodicWorkPolicy.KEEP
,即使更换工期或工人,我们也无法更换工作。
有没有办法替换当前请求运行ning之后的请求?
例如,原始请求运行每天1次,新请求是每小时1次。下一个原始请求运行后,再替换为新的请求
没有办法以干净的方式通过周期性工作准确地完成您想要的事情。
但是,完全没有必要使用周期性工作本身。通过在 doWork
方法的末尾安排下一个 WorkRequest,就在返回 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没有解决方案,但你可以在sharedPreferences中保存间隔并检查间隔是否被改变。并基于此使用 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);
}