Getting Started with Coroutines on AndroidBrandon WeverBlockedUnblockFollowFollowingJan 28Threading on Android has been a hard problem since the start.
From your first NetworkOnMainThreadException to a laggy RecyclerView, we’ve all had at least one threading issue in our apps.
There are many ways to write asynchronous code on Android.
AsyncTask was recommended for a while, then abused, now is the butt of many jokes.
Loaders were introduced and if you could figure out their API they got the job done.
IntentService was a handy way to deal with getting off the main thread, but came with the baggage of bundles and receivers.
RxJava can still be considered the gold standard of threading, but ultimately is more than most applications really need.
Kotlin recently introduced the newest way to deal with asynchronous behavior with coroutines.
I’m not an expert on either of those languages, but that is what I’ve been told.
The power of coroutines is they allow developers to write asynchronous code that reads like it is synchronous.
One of the most common use cases for coroutines on Android would be fetching data from the network.
While libraries like Retrofit may already have some thread awareness with methods like enqueue() they force us to write callback heavy code.
Callbacks are nice when they are simple, but can easily lead to confusion when more than one is needed, or when multiple calls need to happen in parallel.
RxJava would be a nice library to use, but only using it for networking is like using a flamethrower to light a birthday candle.
Getting StartedTo get started with coroutines on Android you will first need to pull in the following dependencies.
1")These libraries give you access to the coroutines API and a special dispatcher that represents the main thread on Android.
Other popular UI frameworks have support for coroutines as well, such as JavaFx and Swing.
Now that we have the tools we need we can start using them and breaking things.
Since we want to do a network request in the example, we will also pull in OkHttp and Moshi (two must know libraries from Square).
Make the CallWe’ll create a WebService class responsible for fetching a Todo from the JSONPlaceholder API.
The WebService should return a NetworkResult of either Success or Failure, which we will model with a sealed class.
The body of the response should also be parsed into a Kotlin data class using Moshi.
The code should look very simple.
There are no callbacks or worrying about what thread we are on.
We are returning a coroutine built with the suspendCoroutine function, which has a continuation as a parameter.
We call the continuation when we want to return values from the coroutine.
The values we return are wrapped in a Result class, which makes it obvious if our code succeeded or failed.
The only other difference between this function and a synchronous function is the suspend keyword.
A function that is marked as such is able to suspend without blocking a thread, which is important for getting 60fps smooth UI.
We cannot call this function like normal functions because of the suspend keyword.
For a suspending function to be called we must provide the Kotlin compiler with some scope of where the function is going to be running.
The way we do this is by creating a CoroutineScope.
(CoroutineScopes and CoroutineContexts are still a bit confusing to me, but I have one that I know works, so if you know a better way to do what I’m about to show, let me know.
)Calling from an ActivityWe need to define our scopes.
We will be calling the network from the IO Dispatcher, and calling the UI with the Main Dispatcher.
Both the Dispatchers will be combined with an object called a Job .
As far as I know, a Job is an object that allows coroutines to be cancelled.
The Job for this Activity is cancelled in onPause, so there is no running tasks when the Activity is paused.
We were able to get off of the main thread, call the network from the IO dispatcher, get back onto the main thread and update the UI.
The code for doing so is incredibly simple and could probably be simpler with some more practice.
Kotlin coroutines are a very powerful tool that is moving quickly in the ecosystem.
Best practices are still being found and I’m definitely still learning.
If you have comments or suggestions about the code I’ve posted definitely let me know in the comments below.
Thanks for reading!.