WorkManager的OneTimeWorkRequest的重试策略/机制是什么

时间:2018-05-23 10:06:54

标签: android android-architecture-components android-workmanager

我有以下一次性工作人员。

// Create a Constraints that defines when the task should run
Constraints constraints = new Constraints.Builder()
        .setRequiredNetworkType(NetworkType.UNMETERED)
        .setRequiresBatteryNotLow(true)
        // Many other constraints are available, see the
        // Constraints.Builder reference
        .build();

OneTimeWorkRequest oneTimeWorkRequest =
        new OneTimeWorkRequest.Builder(SyncWorker.class)
                .setConstraints(constraints)
                .addTag(SyncWorker.TAG)
                .build();

根据https://developer.android.com/topic/libraries/architecture/workmanager

// (Returning RETRY tells WorkManager to try this task again
// later; FAILURE says not to try again.)

我想知道,如果SyncWorker继续RETRY,那么WorkManager的重试策略是什么?例如,WorkManager的最大重试次数是多少?文档目前还不清楚。

3 个答案:

答案 0 :(得分:10)

默认值为BackoffPolicy.EXPONENTIAL。 我们仅在您通过返回RETRYWorkerResult.RETRY所需的约束现在未得到满足时要求我们Worker时重试。因此对于例如如果您需要NETWORK约束,现在设备失去了活动Network连接 - 那么Worker将被停止并自动重试(当满足约束时)。

有关更多信息,请查看docs

答案 1 :(得分:1)

runAttemptCount 获取任何工作的当前运行尝试计数。请注意,对于定期工作,此值会在不同时期之间重置。链接:-

https://developer.android.com/reference/androidx/work/ListenableWorker#getRunAttemptCount()

示例:

override fun doWork(): Result {

    if (runAttemptCount < maxRetryConstantIWant) {
    ..... 
    .....
    .....
    } else { Result.Failure }
}

这里的 runAttemptCount 是工作方法。

答案 2 :(得分:0)

下面的示例在退出之前对捕获的Exception重试3次。

class RepeatWorker(context : Context, params : WorkerParameters)
: Worker(context, params) {

private fun doSomeThing() {
    // do something
}

override fun doWork(): Result {

    if (runAttemptCount > 3) {
        return Result.failure()
    }

    try {
        doSomeThing()
    }
    catch (e: Exception) {
        e.printStackTrace()
        return Result.retry()
    }
    return Result.success()
}

}

注意:默认的BackoffPolicy是指数的,其中30s内进行第一次重试(最小重试时间为10s,最大重试时间永远不会超过18000s / 5小时)。

    fun start() : LiveData<WorkInfo> {
val WORK_NAME = "SingleBackupWorker"

val constraints = Constraints.Builder()
        .setRequiredNetworkType(NetworkType.CONNECTED)
        .build()

val work = OneTimeWorkRequestBuilder<BackupWorker>()
        .setConstraints(constraints)
        .setInitialDelay(5, TimeUnit.SECONDS)
        .setBackoffCriteria(BackoffPolicy.EXPONENTIAL, 1, TimeUnit.MINUTES)
        .build()

WorkManager.getInstance().enqueueUniqueWork(WORK_NAME, ExistingWorkPolicy.REPLACE, work)

return WorkManager.getInstance().getWorkInfoByIdLiveData(work.id)

}