Android Worker Max Retries

Debug Labs
2 min readNov 24, 2023

--

Background : While working with WorkManager on Android if there is a handled exception within doWork() we can ask the WorkManager to retry the work and consequently the doWork() will get executed again .

So when will the work get executed again ? Back-Off Policy (as long as Work Constraints are met)

Use case : The work kept on retrying on every interval (indefinitely) as computed through the Back-Off Policy. I wanted to make sure that after five retries the work fails and we log that failure appropriately.

I also wanted to make sure all unit and integration tests passed.

Solution:

Even though there is no direct API to set Max retries (to five in my case) there is a method in WorkParameters getRunAttemptCount() . This “Gets the current run attempt count for this work. Note that for periodic work, this value gets reset between periods.”

Note that runAttemptCount starts from 0

Sample CoroutineWorker doWork method -

override suspend fun doWork(): Result {
return if (runAttemptCount < 5) { // runAttemptCount starts from 0
try {
// do long running work
} catch (ex: IOException) {
Result.retry()
}
Result.success()
} else {
Result.failure()
}
}

Testing :

use TestListenableWorkerBuilder to test CoroutineWorker implementations, as the work-testing artifact uses Dispatchers.Default rather than your worker implementation’s CoroutineDispatcher

Unit Tests for coroutine worker with MAX_RETRIES

@Test
fun testWorkerSucceedsIfRunAttemptIsLessThanMax() {
val worker = TestListenableWorkerBuilder<LongRunningWorker>(
context = ApplicationProvider.getApplicationContext(),
runAttemptCount = MAX_RETRIES - 1
).build()
runBlocking {
val result = worker.doWork()
assertThat(result, `is`(ListenableWorker.Result.Success()))
}

}

@Test
fun testWorkerFailsIfRunAttemptIsAtMax() {
val worker = TestListenableWorkerBuilder<LongRunningWorker>(
context = ApplicationProvider.getApplicationContext(),
runAttemptCount = MAX_RETRIES
).build()
runBlocking {
val result = worker.doWork()
assertThat(result, `is`(ListenableWorker.Result.Failure()))
}
}

Sample Code on Git

https://github.com/ChaitanyaDuse/WorkManagerSamples

Resources

--

--

Debug Labs
Debug Labs

Written by Debug Labs

🚀 Android Dev (13+ yrs) | Jetpack Compose | AI & ML Enthusiast | Writing on Background Work, Room DB, Clean Architecture & more | Simplifying dev concepts

No responses yet