Coroutines in Android

Mohit Mahajan
Xebia Engineering Blog
3 min readMay 27, 2021

--

Coroutines help to manage long-running tasks that might otherwise block the main thread and cause your app to become unresponsive. A coroutine is a concurrency design pattern that you can use on Android to simplify code that executes asynchronously

As you see in above diagram, in your main thread you can perform only small operations. If you want to perform long running operations in your main thread then your app might be crash and slow. Or if you create no. of background/worker thread then out of memory issue is coming. Coroutines are a special type of function that deliberately yield control over to the caller, but does not end its context in the process, instead maintaining it in an idle state.

How to use Coroutines?

dependencies
{
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:x.x.x"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:x.x.x"
}

Coroutine defines a series of rules and configurations that define how and where a coroutine is going to be executed.

  • Main: uses the UI Thread. In Rx is similar to AndroidSchedulers.MainThread()
  • Default: used for CPU intensive tasks. It is going to use as many threads as CPU cores are available. Since they are CPU intensive tasks, there is no point in having many threads running, as the CPU is going to be busy. Similar to Schedulers.computation() in Rx.
  • IO: used for Input/Output. Making a request to an API, access to a DB, etc. Similar to Schedulers.io() in Rx.
  • Job: It’s essentially a task that runs in background, and it can be interpreted as an action, with a lifecycle that gets destroyed once finished.
  • For run different operations using jobs: Job.join
  • For cancels all the children jobs: Job.cancel
  • withContext: another way of writing the async where we do not have to write await().
suspend fun fetchUser(): User {
return withContext(Dispatchers.IO) {
// make network call
// return user
}
}

When we use withContext, it will run in series instead of parallel. That is a major difference.

Coroutines functions in Kotlin

Suspend : As their name suggests, they are functions that suspend the execution of a coroutine at some point, and then resume the execution of the function again when the result is ready.

suspend fun makeNetworkRequest() {
// fetchData is another suspend function, so 'makeNetworkRequest' is going to be `suspended`
// until it's result becomes available, without blocking the main thread.
val result = fetchData()
// continues executing once the result becomes available
show(result)
}

// fetchData is main thread safe
suspend fun fetchData(): Result { ... }

Launch Function

The launch will not block the main thread, but on the other hand, the execution of the rest part of the code will not wait for the launch result since launch is not a suspend call.

fun GFG()
{
var resultOne = "Android"
var resultTwo = "Kotlin"
Log.i("Launch", "Before")
launch(Dispatchers.IO) { resultOne = function1() }
launch(Dispatchers.IO) { resultTwo = function2() }
Log.i("Launch", "After")
val resultText = resultOne + resultTwo
Log.i("Launch", resultText)
}

suspend fun function1(): String
{
delay(1000L)
val message = "function1"
Log.i("Launch", message)
return message
}

suspend fun function2(): String
{
delay(100L)
val message = "function2"
Log.i("Launch", message)
return message
}

Async Function

Async is also used to start the coroutines, but it blocks the main thread at the entry point of the await() function in the program.

fun GFG
{
Log.i("Async", "Before")
val resultOne = Async(Dispatchers.IO) { function1() }
val resultTwo = Async(Dispatchers.IO) { function2() }
Log.i("Async", "After")
val resultText = resultOne.await() + resultTwo.await()
Log.i("Async", resultText)
}

suspend fun function1(): String
{
delay(1000L)
val message = "function1"
Log.i("Async", message)
return message
}

suspend fun function2(): String
{
delay(100L)
val message = "function2"
Log.i("Async", message)
return message
}

Launch vs Async

Benefits using Coroutines

  • Coroutines are Light-weight Threads
  • Coroutines can run in parallel, wait for each other and communicate with each other
  • Create thousands of coroutines without any memory issue
  • Best for modern applications

--

--