Kotlin Coroutines + Android

rajan ks
5 min readNov 26, 2019

As a Android Developer by profession, I’ve always wanted to keep my tech stack sorted. When co-routines as a feature first introduced in Kotlin-Conf, suspend functions, scopes, context seemed strange and complex to me as I was already pretty happy tackling concurrency using the powerful RxJava.

But when I heard people say that you can literally create thousands of coroutines in your code without any downside to performance and can write asynchronous code sequentially, it grabbed my attention. I’ve desperately wanted to know what are they, how do they work under the hood and benefits of using them, so I’ve went through lot of Tutorials, Official docs, Tech conferences, Dev summits on coroutines and with all the knowledge I’ve gathered on coroutines I’m going to write down a detailed summary of my understanding on Coroutines in Kotlin.

What is a Coroutine by definition ?

Coroutines are light weight threads.

I hope many of you might be familiar with above statement, but what actually are light weight threads?

A Native Thread in any language is the smallest unit of processing performed inside core of a CPU.

While coroutines are similar to threads in aspect of context switching and communication, they are not actually threads in terms of execution.

Then what really are coroutines ?

A coroutine as name suggests (co=sub ,routine=function), is a special kind of function which can suspend and resume it’s execution when needed.

What does that mean ?

When you run a thread, it will have actual context switching in terms of CPU but coroutines are just a function which are stackless and will be executed using single/different threads based on scope.

Coroutines are based on Java Continuations, where a suspend function can maintain it’s state when suspended and resume from the same state when needed.

let’s look at some code

Whenever control encounters suspend keyword, it only suspends the current coroutine but not the thread which executing the coroutine, so the thread is free to take up other work or run other coroutines.

Coroutines are functions which can suspend and resume it’s execution where as threads in other hands are responsible for executing coroutines.

In this way a single thread can execute ‘n’ number of coroutines. Also a single coroutine can be run by different threads based on needs.

Coroutines are designed to write asynchronous code in sequential non-blocking manner.

Coroutines are alternative for callbacks, you can write code sequentially and expect it run asynchronously.

code again

Okay, So far we’ve made one thing clear that coroutines needs a thread to execute, but how coroutines decide on which thread it should run?

CoroutineContext

Coroutines always execute in some context represented by a value of the CoroutineContext type, defined in the Kotlin standard library.

meaning coroutine needs a environment to run which is created using context, which in terms holds information about state of coroutine like Job and Dispatcher information.

Job is a cancellable thing with a life-cycle that culminates in its completion. Think of Job as something similar to disposable in RxJava which holds the state of background work, a Job in fact doesn’t return the value on execution, it is used to cancel coroutine, to know the state of coroutine etc.

Tip : Coroutines always works in parent-child hierarchy where in if you cancel a parent all it’s children gets cancelled too and an error in single child results in cancellation of parent and it’s siblings.

Still we haven’t figured how coroutines decides on threads, as we know CoroutineContext has one more element called Dispatcher which is responsible for assigning threads to coroutine

Dispatcher

The coroutine context includes a coroutine dispatcher that determines what thread or threads the corresponding coroutine uses for its execution. The coroutine dispatcher can confine coroutine execution to a specific thread, dispatch it to a thread pool, or let it run unconfined.

By default coroutines provide 3 main dispatchers for Android

  • Default — Which creates a thread pool based on max cores of CPU to
    perform CPU intense operations
  • IO — Which is used for network or Disk operations by creating separate worker threads
  • Main — Which is indeed the Main thread of Android Framework.

Awesome, now lets look at how to use Dispatchers to inform coroutines to work with them

Before getting there , we need to discuss two other topics of coroutines

  • CoroutineScope
    Defines a scope for new coroutines. Every coroutine builder is an extension on CoroutineScope and inherits its coroutineContext to automatically propagate both context elements and cancellation.
    You cannot write or call an coroutine block outside coroutine scope, every coroutine needs to encapsulated inside a scope. The best ways to obtain a standalone instance of the scope are CoroutineScope and MainScope factory functions. Additional context elements can be appended to the scope using the plus operator.
    A scope has a context, so when you are creating a scope you pass the dispatchers and job using plus operator.

Let’s look at an example

  • CoroutineBuilders
    Now we have scope, we need start spawning coroutines so we can actually execute some piece of code in them, to do that we need CoroutineBuilders, framework provides launch and async builders which are nothing but an extension functions of scope. You can also create your own builders, we’ll come to that later.

launch is like a start for coroutines , where it will start execution. When you don’t pass the context(Dispatcher) to launch , it will run on context of parent.

Async on other hand is similar to launch except it returns Deferred<T> instead of job, which you can call await on to get the result of execution at later point of time.

withContext
Also you can switch the context of execution inside a coroutine using withContext suspend function.

If you have reached here, We almost covered major aspects of coroutines, what it is, how it executes, how to create it.

Now comes the best part which actually demonstrates how powerful and simple it is to use along Android.

You need to add below two dependencies to your gradle file in Android project to access coroutines in your App

build.gradle

I’m gonna demonstrate few android samples like postDelayed, Timers, network call and bitmap processing using coroutines.

Before that I’m gonna create few extension functions on CoroutineScope which will come handy for us to use in Android

Let’s create a scope for an Base Android Activity using which we can run coroutines

We pretty much have everything ready, let’s get started

That’s all for now folks. I hope this tutorial served it’s purpose.Please drop any suggestions, modifications, thoughts or queries in comments.

Stay tuned for more!

--

--

rajan ks

Software Engineer at Facebook. Android Enthusiast, Online gamer.