使用 WorkManager 中的 PeriodicWorkRequest

13

由于WorkManager是在Google I/O上新引入的,我正在尝试使用workmanager定期执行任务。

我的做法是使用PeriodicWorkRequest来计划工作,如下所示:

Constraints constraints = new Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build();
PeriodicWorkRequest build = new PeriodicWorkRequest.Builder(SyncJobWorker.class, MY_SCHEDULE_TIME, TimeUnit.MILLISECONDS)
           .addTag(TAG)
           .setConstraints(constraints)
           .build();

WorkManager instance = WorkManager.getInstance();
if (instance != null) {
          instance.enqueueUniquePeriodicWork(TAG, ExistingPeriodicWorkPolicy.REPLACE, build);
}

我遇到的问题是,当我请求PeriodicWorkRequest时,它会立即开始工作。

  • 有人知道如何停止立即执行的工作吗?在使用PeriodicWorkRequest时。
  • 还想知道如何重新安排工作?如果我想更改已计划工作的时间怎么办?

我正在使用:implementation "android.arch.work:work-runtime:1.0.0-alpha04"

希望能得到任何帮助。


1
你找到设置PeriodicWorkRequest的初始延迟的解决方案了吗? - Jay Patel
实际上,我还没有尝试过最新版本的工作管理器,所以不清楚。 - Uttam Panchasara
我尝试了最新的 alpha 版本,但没有成功。 - Jay Patel
如果我找到解决方案,我会进行更新。 - Uttam Panchasara
5个回答

20

您可以使用PeriodicWorkRequest.Builder中的flex period来实现此操作。

例如,如果您想在重复间隔结束时的15分钟内运行Worker(假设为8小时),则代码将如下所示:

val periodicRefreshRequest = PeriodicWorkRequest.Builder(
            RefreshWorker::class.java, // Your worker class
            8, // repeating interval
            TimeUnit.HOURS,
            15, // flex interval - worker will run somewhen within this period of time, but at the end of repeating interval
            TimeUnit.MINUTES
    )

视觉说明


3

你需要在构建器中添加initialDelay

fun scheduleRecurringFetchWeatherSyncUsingWorker() {
    val constraints: Constraints = Constraints.Builder().apply {
        setRequiredNetworkType(NetworkType.CONNECTED)
        setRequiresBatteryNotLow(true)
    }.build()

    val request: PeriodicWorkRequest = PeriodicWorkRequest.Builder(
        MySimpleWorker::class.java, 3, TimeUnit.HOURS, 1, TimeUnit.HOURS)
        .setConstraints(constraints)
        .setInitialDelay(2, TimeUnit.HOURS)
        .setBackoffCriteria(BackoffPolicy.LINEAR, 1, TimeUnit.HOURS)
        .build()
    mWorkManager.enqueueUniquePeriodicWork(
        TAG_WORK_NAME,
        ExistingPeriodicWorkPolicy.KEEP,
        request
    )
}

谢谢,初始延迟在 alpha 版本中之前不存在。 - Uttam Panchasara

0

你可以使用setInitialDelay来延迟任务。这对于OneTimeWorkRequestPeriodicWorkRequest都适用。

val myWorkRequest = OneTimeWorkRequestBuilder<MyWork>()
   .setInitialDelay(10, TimeUnit.MINUTES)
   .build()

对于PeriodicWorkRequest,只有第一次运行周期性工作会被延迟。


0

你的代码总是重新安排工作,因此你可以根据需要更改工作参数

instance.enqueueUniquePeriodicWork(TAG, ExistingPeriodicWorkPolicy.REPLACE, build);

如果您想保持工作参数不变(即使在重新启动后),而不进行任何更改,请使用以下命令:
instance.enqueueUniquePeriodicWork(TAG, ExistingPeriodicWorkPolicy.KEEP, build);

如果需要调度,则只有在工作未排队时才会进行调度。

要停止工作任务,请使用

// cancel the unique work
instance.cancelUniqueWork(TAG);
// clear all finished or cancelled tasks from the WorkManager 
instance.pruneWork();

顺便说一下,我认为使用相同的标签作为唯一工作ID和任务标签并不是一个好方法。如果您需要唯一的工作ID,则根本不需要任务标签。任务标签是用于当您想要有多个任务的情况。

@UttamPanchasara,有什么问题没有正常工作吗?我在我的应用程序对象的OnCreate()中使用ExistingPeriodicWorkPolicy.KEEP,在任务设置中使用ExistingPeriodicWorkPolicy.REPLACE(例如使用不同的时间间隔进行调度)。对我来说,它非常好用。我也尝试了instance.wm.cancelUniqueWork(TAG),对我来说它也可以正常工作。顺便说一下,我使用的是"android.arch.work:work-runtime:1.0.0-alpha10"。 - Alex
你解释的策略方式对我不起作用,而且我还没有尝试最新的工作管理器版本。 - Uttam Panchasara

-1

为了延迟任务,您可以使用setInitialDelay。

我们使用setInitialDelay来确保通知在事件当天而不是立即触发。这个延迟是由一个单独的方法计算出来的,该方法返回现在和通知应该在事件日期(中午)触发之间的毫秒数。请注意,这个延迟并不总是准确的!由于现代Android的工作方式,您的工作可能会被多种因素延迟,因此对于非常时间敏感的目的要注意这一点。

所有信息都在这篇文章中。https://medium.com/@eydryan/scheduling-notifications-on-android-with-workmanager-6d84b7f64613


1
setInitialDelay 只能用于一次性请求,而我正在使用周期性工作请求进行调度。 - Uttam Panchasara
1
@UttamPanchasara 现在 PeriodicWorkRequest 支持初始延迟(参见此处 - Vadim Kotov
感谢您的更新,@Valim,这个功能确实非常有帮助。 - Uttam Panchasara

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接