英文:
Periodic work isn't enqued after several successful executions
问题
I can provide a translation of the code for you:
我正在使用 Android 的 WorkManager(使用 `androidx.work:work-runtime-ktx:2.8.1`)安排定期工作。在几次成功执行后,定期工作停止执行。
我安排的任务是每天备份任务。它会将大约 500KB 的数据备份到 Google Drive。有任何想法,为什么在几次成功执行后任务会停止运行?
这是定期工作的代码:
```kotlin
@Keep
class BackupWorker(appContext: Context, workerParams: WorkerParameters) : Worker(appContext, workerParams) {
@Inject lateinit var backupToDriveUseCase: BackupToDriveUseCase
init {
applicationContext.appComponent.inject(this)
}
override fun doWork(): Result {
return try {
runBlocking { backupToDriveUseCase.backup() }
Result.success()
} catch (e: Exception) {
Firebase.crashlytics.recordException(e)
Result.retry()
}
}
}
<details>
<summary>英文:</summary>
I'm scheduling a periodic work with Android's WorkManager (using `androidx.work:work-runtime-ktx:2.8.1`). After several successful executions, the periodic work stops being executed.
The task I'm scheduling is a daily backup task. It backs up about 500KB of data to Google Drive. Any idea why after several successful executions the task would stop running?
fun schedule(frequency: BackupFrequency) {
biLogger.scheduleBackup(preferences.getBackupFrequency())
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build()
val backupRequest = PeriodicWorkRequest.Builder(
BackupWorker::class.java,
24,
TimeUnit.HOURS,
4,
TimeUnit.HOURS,
)
.setConstraints(constraints)
.build()
WorkManager.getInstance(context).enqueueUniquePeriodicWork(
UNIQUE_JOB_NAME,
ExistingPeriodicWorkPolicy.UPDATE,
backupRequest
)
}
This is the periodic work:
@Keep
class BackupWorker(appContext: Context, workerParams: WorkerParameters) : Worker(appContext, workerParams) {
@Inject lateinit var backupToDriveUseCase: BackupToDriveUseCase
init {
applicationContext.appComponent.inject(this)
}
override fun doWork(): Result {
return try {
runBlocking { backupToDriveUseCase.backup() }
Result.success()
} catch (e: Exception) {
Firebase.crashlytics.recordException(e)
Result.retry()
}
}
}
</details>
# 答案1
**得分**: 1
以下是翻译好的部分:
有一些明显的原因,我猜想这些原因可能不适用,比如 Android 设备没有网络(未满足约束条件),或者完全关机。
你有没有想法,设备在此期间发生了什么?
根据我的经验,重复间隔是从上次发生或者从 Android 设备启动开始计算的。所以,如果发生了重新启动,事件将被延迟到(在你的情况下)重新启动后的 24 小时。
在我们的解决方案中,针对符合 PCIv4 要求的 Android 设备(意味着每 24 小时必须重新启动一次),我不得不更改调度程序,不再使用周期性调度,而是使用 `OneTimeWorkRequest.Builder`,手动计算延迟并计划下一次发生。
<details>
<summary>英文:</summary>
There are the obvious reasons, which - I guess - are not the case, like the android device does not have network (not met constraint), or is turned off completely.
Do you have any idea, what is happening with the device in the meantime?
From my experience, the repeat interval is computed from last occurence, or **from the start of android device**. So if there was a reboot, the occurence will be delayed to (in your case) 24 hours after the reboot.
In our solution, working on an android device under PCIv4 requirement - means mandatory reboot once in 24hours, I had to change the scheduler, to not work with Periodic... but with `OneTimeWorkRequest.Builder`, computing delay *by hand* and planning next occurence.
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论