在前面的章节中,我们已经提到了工作约束这个词,但是相关的内容没有讲解。同时前面也已经使用到了延迟的相关方法。所以本章节中将讲解工作约束的相关内容。
WorkManager的工作约束
约束可确保将工作延迟到满足最佳条件时运行。以下约束适用于 WorkManager。
NETWORKTYPE | 约束运行工作所需的网络类型。例如 WI-FI (UNMETERED )。 |
---|---|
BatteryNotLow | 如果设置为 true,那么当设备处于“电量不足模式”时,工作不会运行。 |
RequiresCharging | 如果设置为 true,那么工作只能在设备充电时运行。 |
DeviceIdle | 如果设置为 true,则要求用户的设备必须处于空闲状态,才能运行工作。如果您要运行批量操作,否则可能会降低用户设备上正在积极运行的其他应用的性能,建议您使用此约束。 |
StorageNotLow | 如果设置为 true,那么当用户设备上的存储空间不足时,工作不会运行。 |
如需创建一组约束并将其与某项工作相关联,请使用一个 Contraints.Builder()
创建 Constraints
实例,并将该实例分配给 WorkRequest.Builder()
。
例如,以下代码会构建了一个工作请求,该工作请求仅在用户设备正在充电且连接到 Wi-Fi 网络时才会运行:
Constraints constraints = new Constraints.Builder()
.setRequiredNetworkType(NetworkType.UNMETERED) //设置连接到WiFi
.setRequiresCharging(true) //设置正在充电
.build();
WorkRequest myWorkRequest =
new OneTimeWorkRequest.Builder(MyWork.class)
.setConstraints(constraints)
.build();
如果指定了多个约束,工作将仅在满足所有约束时才会运行。
如果在工作运行时不再满足某个约束,WorkManager 将停止工作器。系统将在满足所有约束后重试工作。
WorkRequest的延迟工作
如果工作没有约束,或者当工作加入队列时所有约束都得到了满足,那么系统可能会选择立即运行该工作。如果您不希望工作立即运行,可以将工作指定为在经过一段最短初始延迟时间后再启动。
下面举例说明了如何将工作设置为在加入队列后至少经过 10 分钟后再运行。
WorkRequest myWorkRequest =
new OneTimeWorkRequest.Builder(MyWork.class)
.setInitialDelay(10, TimeUnit.MINUTES)
.build();
该示例说明了如何为 OneTimeWorkRequest
设置初始延迟时间,您也可以为 PeriodicWorkRequest
设置初始延迟时间。在这种情况下,定期工作只有首次运行时会延迟。
WorkManager的重试&退避政策
如果您需要让 WorkManager 重试工作,可以从工作器返回 Result.retry()
。然后,系统将根据退避延迟时间和退避政策重新调度工作。
- 退避延迟时间指定了首次尝试后重试工作前的最短等待时间。此值不能超过 MIN_BACKOFF_MILLIS(10秒 )。
- 退避政策定义了在后续重试过程中,退避延迟时间随时间以怎样的方式增长。WorkManager 支持 2 个退避政策,即
LINEAR
和EXPONENTIAL
。
每个工作请求都有退避政策和退避延迟时间。默认政策是 EXPONENTIAL
,延迟时间为 10 秒,但您可以在工作请求配置中替换此设置。
以下是自定义退避延迟时间和政策的示例。
WorkRequest myWorkRequest =
new OneTimeWorkRequest.Builder(MyWork.class)
.setBackoffCriteria(
BackoffPolicy.LINEAR,
OneTimeWorkRequest.MIN_BACKOFF_MILLIS,
TimeUnit.MILLISECONDS)
.build();
在本示例中,最短退避延迟时间设置为允许的最小值,即 10 秒。由于政策为 LINEAR
,每次尝试重试时,重试间隔都会增加约 10 秒。例如,第一次运行以 Result.retry()
结束并在 10 秒后重试;然后,如果工作在后续尝试后继续返回 Result.retry()
,那么接下来会在 20 秒、30 秒、40 秒后重试,以此类推。如果退避政策设置为 EXPONENTIAL
,那么重试时长序列将接近 20、40、80 秒,以此类推。
※注意:退避延迟时间不精确,在两次重试之间可能会有几秒钟的差异,但绝不会低于配置中指定的初始退避延迟时间。
参照文献: