【问题标题】:How to change periodic work request period without it running immediately using WorkManager?如何使用 WorkManager 在不立即运行的情况下更改定期工作请求周期?
【发布时间】:2018-10-10 03:35:24
【问题描述】:
val request = PeriodicWorkRequestBuilder<FooWorker>(1, TimeUnit.DAYS).build()
WorkManager.getInstance().enqueueUniquePeriodicWork(
    "FOO",
    ExistingPeriodicWorkPolicy.REPLACE,
    request
)

上面的代码在ApplicationonCreate 中运行,以确保请求入队。但是,这将导致一个问题,即每次用户启动应用程序时FooWorker 都会运行,因为ExistingPeriodicWorkPolicy.REPLACE 取消以前的工作并将新工作排入队列,这会导致它立即运行。

如果我们换成ExistingPeriodicWorkPolicy.KEEP,即使换了工期,也换不了工。

有没有办法在当前请求运行后替换请求?

例如,源请求每天运行 1 次,新请求每小时运行 1 次。运行下一个源请求后,将其替换为新请求。

【问题讨论】:

    标签: android kotlin android-workmanager


    【解决方案1】:

    没有办法以干净的方式通过定期工作完全满足您的需求。

    但是,绝对没有必要使用周期性工作本身。通过在您的 doWork 方法的末尾、返回 Result.SUCCESS 之前安排下一个 WorkRequest 可以轻松完成相同的结构:

    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
    }
    

    通过此设置,如果您已经有一个 WorkRequest 排队,并且当该排队的工作触发时,下一个 WorkRequest 将与合适的新时期。

    【讨论】:

      【解决方案2】:

      看起来现在有一种方法可以用enqueueUniquePeriodicWork 替换定期工作。

        val request = PeriodicWorkRequest.Builder(FooWorker::class.java, 1, TimeUnit.DAYS).build()
        WorkManager.getInstance(appContext)
        .enqueueUniquePeriodicWork(WORK_TAG, ExistingPeriodicWorkPolicy.REPLACE, request)
      

      确保您传递的是 ExistingPeriodicWorkPolicy 而不是 ExistingWorkPolicy

      【讨论】:

        【解决方案3】:

        如果您想使用ExistingPeriodicWorkPolicy.KEEP 并仅在您想更改重复间隔时更新 PeriodicWorkRequest,WorkManager 没有解决方案,但您可以将间隔保存在 sharedPreferences 中并检查间隔是否已更改。并基于此使用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);
            }
        

        【讨论】:

        • 在 doWork() 中获得 API 结果后,我也在做同样的事情,但对我来说,doWork() 再次调用。所以它会循环。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-10-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多