Modified (Original Photo by Nick Dietrich on Unsplash)

Android Kotlin Coroutines: Basic Terminologies & Usage

The common terms used in Coroutines. Knowing these terms in advance will ease your learning process.

Rohit Surwase
AndroidPub
Published in
7 min readOct 17, 2018

--

This article is a brief summary of official Kotlin doc and a few other resources that I have gone through over time during my learning. This is my attempt to simplify common terms used in the context of coroutines and give you the taste of the power, coroutine gives you which would inspire you to jump in the world of coroutines as asynchronous or non-blocking programming is a new reality.

Developing Apps using Kotlin is really fun. Code less, perform better suits very well for Kotlin. And with coroutines, it becomes sweeter. Coroutines are now stable and can be used within an early-access-preview version of Kotlin v1.3. So, it is the best time to learn about coroutines and start using it in your Android projects.

What are Coroutines?

“A coroutine is an instance of suspendable computation, conceptually similar to a thread, in the sense that it takes a block of code to run and has a similar life-cycle, it is created and started, but it is not bound to any particular thread. It may suspend its execution in one thread and resume in another one. Moreover, like a future or promise, it may complete with some result or exception.”

Coroutines are lightweight threads and they are so cheap to create which open the doors to asynchronous programming for developers. This means we can call more than one functions asynchronously and get the result in a shorter duration in very effective way. Now imagine how faster our validations would be as we can call them asynchronously. All those things (API calls, Database access…) which need a background thread to process are just a few lines away than creating separate worker threads for it and then managing it. And making coroutines life-cycle aware is so simple.

suspend fun validateEntries(str: String): Boolean =
coroutineScope {
val deferred1 = async { firstValidation(str) }
val deferred2 = async { secondValidation(str) }
deferred1.await() && deferred2.await()
}

Coroutine is language feature of Kotlin, it means Kotlin provides core level APIs (like suspending function) which enable various other libraries to utilize coroutines such as kotlinx.coroutines, a library developed by JetBrains which need to be added in any Kotlin project which provides a number of high-level coroutine-enabled primitives. Otherwise, you can directly use core level APIs to build your own.

If you are curious about adding the latest stable version of coroutines to your project, you can refer the link I have shared at the end of this article.

Suspending Function

“A suspending function (marked with suspend modifier) may suspend the execution of the code without blocking the current thread of execution by invoking other suspending functions.” So how does it work? Instead of returning just result, a suspending function also returns context which is used by the caller. In simple words, it is a function which executes a part of the code and then suspends while keeping the context and reference to the remaining code (like a lambda consisting remaining code). So whenever the function resumes it has the context and the remaining code that need to be executed. Suspending functions are only allowed to be called from a coroutine or another suspend function.

CoroutineBuilder

“A function that takes some suspending lambda (lambda marked with suspend modifier) as an argument, creates a coroutine, and, optionally, gives access to its result in some form.”

fun suspendableLambda(block: suspend () -> Unit) = //...

Few of coroutine builders provided by kotlinx.coroutines:
launch {}: Launch a coroutine that does not have any result, it returns Job.
async{}: Returns a single value result using Deffered- a light-weight non-blocking future that represents a promise to provide a result later. So, we can use .await() on a deferred value to get its eventual result, but Deferred is also a Job, so we can cancel it if needed.
runBlocking{}: Blocks current thread until the execution of coroutine.

delay is a special suspending function that does not block a thread but suspends coroutine.

CoroutineScope

Each coroutine run inside a scope defined by us, so we can make it application wide or specific for a view with well-defined life-cycle such as Activities or Fragments. Every coroutine builder is an extension on CoroutineScope. Each coroutine waits for all the coroutines inside their block/scope to complete before completing themselves.
CoroutineScope provides properties like coroutineContext and it is a set of various elements like Job of the coroutine and its dispatcher. We can check whether coroutine is active or not using isActive property of Job. GlobalScope is used to launch a coroutine with a lifetime of the whole application.

CoroutineDispatcher

CoroutineDispatcher can confine (restrict) coroutine execution to a specific thread, dispatch it to a thread pool, or let it run unconfined (unrestricted). It means CoroutineDispatcher determines what thread or threads the corresponding coroutine uses for its execution.

kotlinx.coroutines provides following dispatchers:
Dispatchers.Default: Used by all standard builder if no dispatcher is specified. It uses a common pool of shared background threads. This is an appropriate choice for compute-intensive coroutines that consume CPU resources.
Dispatchers.IO: Uses a shared pool of on-demand created threads and is designed for offloading of IO-intensive blocking operations (like file I/O and blocking socket I/O).
Dispatchers.Unconfined — Unrestricted to any specific thread or pool and should not be used normally in code. There will be certain use-cases where we might need to use this.
newSingleThreadContext: To create new private single-threaded coroutine context.
newFixedThreadPoolContext: To create private thread pool of fixed size.
asCoroutineDispatcher: Extension function to convert Executor to dispatcher.

All coroutines builders like launch and async accept an optional CoroutineContext parameter that can be used to explicitly specify the dispatcher for new coroutine and other context elements. So, launch(Dispatchers.Default) { ... } uses the same dispatcher as GlobalScope.launch { ... }.

Job

“Conceptually, a job is a cancellable thing with a life-cycle that destroys on its completion. It can be arranged into parent-child hierarchies where cancellation of the parent leads to an immediate cancellation of all its children. Failure or cancellation of a child with an exception other than CancellationException immediately cancels its parent. This way, a parent can cancel its own children (including all their children recursively) without canceling itself.”
We can make a job non-cancellable using NonCancellable . Also, we can make a coroutine to cancel itself after timeout using withTimeout function.

Recently, I have started a series which covers MVP & Architecture Components in Kotlin with basic examples without any libraries to give you the exact idea of these patterns.

Actors

An actor is a combination of a coroutine state, behavior and a channel to communicate with other coroutines. Actor processes stream of messages. It can also be used for tasks that should not be performed concurrently. This is useful when we do not want to respond to all back-to-back (unnecessary) clicks by a user on a button but only first or recent click.

Channels

Channel is a non-blocking primitive for communication between sender and receiver. It has suspending operations instead of blocking ones. It provide a way to transfer a stream of values between coroutines. Channels are (till mid of October ’18) an experimental feature of kotlinx.coroutines.

Structured Concurrency

In general programming, threads are global by default but coroutines are always related to some local scope like a UI element with well-defined life-cycle. And we should launch coroutines in the specific scope of the operation we are performing.

Android

In Android, we need a coroutine dispatcher context that restricts the coroutine execution to main UI thread. This can be achived by adding Android specific kotlinx-coroutines-android library dependency along with core library mentioned above. It provides Dispatchers.Main context for Android applications.

I hope, I was able to give you some basic idea of coroutines. If you think I have missed something or something need to be improved/corrected, please comment, I would do necessary changes.

Also, check out Linkaive App, an app to save news, articles, and all useful links for later. One of the best app for users who like to have a collection of their favorite links. I am redesigning this app using Kotlin and Architecture Components.

Link to Add Stable Coroutines to Android-Kotlin Project article.

References & Further Readings

  1. Official coroutines guide: https://kotlinlang.org/docs/reference/coroutines-overview.html
  2. Exploring Coroutines in Kotlin: https://www.youtube.com/watch?v=jT2gHPQ4Z1Q
  3. kotlinx.coroutine library: https://github.com/Kotlin/kotlinx.coroutines
  4. Core primitives to work with coroutines: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/
  5. Guide to UI programming: https://github.com/kotlin/kotlinx.coroutines/blob/master/ui/coroutines-guide-ui.md
  6. Structured Concurrency: https://medium.com/@elizarov/structured-concurrency-722d765aa952

Thanks for reading!
Rohit Surwase

If you liked the article, clap clap clap 👏👏👏 as many times as you can.

LIKED SO MUCH! Medium allows up to 50 claps.
Also, post a Tweet on Twitter.

Let’s be the friends on LinkedIn, Medium, Twitter and GitHub.

Few of my other articles:

--

--

Rohit Surwase
AndroidPub

Techie by Birth. Writer by Hobby. Observer by Nature. Unpredictable by Character. Android Developer (Google Certified) by Profession.