Display the result of the Request without using runOnUIThread

Android requires the UI to be updated on the UI Thread, which is the Main Thread of an app. This, with plain Android (meaning no Rx or other libs) means that we often have to use runOnUiThread after we realize an operation in a background thread that we want to reflect in the UI.

With coroutines we can have a context that guarantees that by default everything is executed in the UI thread, and then we can have some parts of the coroutine to be executed in a background thread. Let’s take another look at MainActivity.kt.

1 launch(Android) {

2 // try

3 val result = SampleClient.fetchPosts()

4 postsAdapter.setElements(result.await())

5 postsAdapter.notifyDataSetChanged()

6 // catch

7 }

launch - Launches new coroutine without blocking current thread and returns a reference to the coroutine as a [Job].

Line 1 is launching a coroutine with the context Android, which is a simple implementation of CoroutineContext that I put here. It is a context that provides an AndroidContinuation, which is a continuation I made to always resume in the main thread. For example:

1 override fun resume(value: T) {

2 if (Looper.myLooper() == Looper.getMainLooper())

3 cont.resume(value)

4 else Handler(Looper.getMainLooper()).post {

5 cont.resume(value)

6 }

7 }

This means that any coroutine executed with that Android context will be resumed in the main thread. That’s the reason why updating and notifying the adapter didn’t require runOnUIThread. The same for displaying the toast if the exception happens.

If you go back and check the code to call the service, async is being executed with the context CommonPool, this context will execute and resume in background, in a shared pool of threads.