Search code examples
androidandroid-workmanager

Periodic work isn't enqued after several successful executions


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()
        }
    }
}

Solution

  • 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.