Save the date! Android Dev Summit is coming to Sunnyvale, CA on Oct 23-24, 2019.

Threading in CoroutineWorker

For Kotlin users, WorkManager provides first-class support for coroutines. To get started, include work-runtime-ktx in your gradle file. Instead of extending Worker, you should extend CoroutineWorker, which has a slightly different API. For example, if you wanted to build a simple CoroutineWorker to perform some network operations, you would do the following:

class CoroutineDownloadWorker(context: Context, params: WorkerParameters) : CoroutineWorker(context, params) {

    override suspend fun doWork(): Result = coroutineScope {
        val jobs = (0 until 100).map {
            async {
                downloadSynchronously("https://www.google.com")
            }
        }

        // awaitAll will throw an exception if a download fails, which CoroutineWorker will treat as a failure
        jobs.awaitAll()
        Result.success()
    }
}

Note that CoroutineWorker.doWork() is a suspending function. Unlike Worker, this code does not run on the Executor specified in your Configuration. Instead, it defaults to Dispatchers.Default. You can customize this by providing your own CoroutineContext. In the above example, you would probably want to do this work on Dispatchers.IO, as follows:

class CoroutineDownloadWorker(context: Context, params: WorkerParameters) : CoroutineWorker(context, params) {

    override val coroutineContext = Dispatchers.IO

    override suspend fun doWork(): Result = coroutineScope {
        val jobs = (0 until 100).map {
            async {
                downloadSynchronously("https://www.google.com")
            }
        }

        // awaitAll will throw an exception if a download fails, which CoroutineWorker will treat as a failure
        jobs.awaitAll()
        Result.success()
    }
}

CoroutineWorkers handle stoppages automatically by cancelling the coroutine and propagating the cancellation signals. You don't need to do anything special to handle work stoppages.