Ever since coroutines were introduced I have been long suffered to read up about them. Whenever I do there always seems to be something in the way. It all seems complicated and long winded. I know we need asynchronous requests, I know threading is a thing. I’m tired of reading articles that defend threading, just show me how to coroutine.

In your app build.gradle:

implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9'

In your Activity:

    private suspend fun longRunningBackgroundThread() {
        doSomeWork()
        runOnUiThread {
            makeACallToMainThread()
        }
    }

    // ...

    someJob = MainScope().launch {
            withContext(Dispatchers.IO) { // ensures running on separate thread
                longRunningBackgroundThread()
            }
        }

    // ...

    someJob.cancel() // if you need to cancel it

AsyncTasks took me forever to adopt, however they eventually won me over because they were Android agnostic and could be used in several places without context. I’m not a fan of boilerplate and Background Services seemed overkill.

I strongly recommend reading the Android Developers Blog and if you have the time, do their codelab, as it takes the reader through testing coroutines. It seems like coroutine scope needs to come from the ViewModel and Google is really pushing for that type of architecture, which I would also recommend. The approach above is designed to be very quick and I think it’s rather dirty.

I think the main reason for pushing the coroutine scope into the ViewModel is that technically, that is where the decision to be asynchronous should be made. Your data layer should be written in a synchronous manner so that you can test it independently. And you should shy away from too much on an Activity / Fragment is because they’re so full of Android state you’ll need to be careful that it is terminated when the Activity / Fragment terminates, lest there be race conditions.