Coroutines For Everyone- Kotlin Guide
In this tutorial we will look in deep about Coroutines concepts used in Android.
So What is Coroutines?
The word “coroutine” is composed of two words: “co” (cooperative) and “routines” (functions). We can assume that Coroutine are set of functions that cooperate with one another without changing the context of the operation. Coroutines are lighter than threads so it enable us to write concurrent code without much effort.
Let’s get Started..
To initiate an Coroutine we need to know some basic components used with Coroutines. These components together called as Coroutine Context.
Coroutine Scope — It is basically the scope in which the coroutine runs with its assigned properties. In Android this coroutine scope varies based on the particular layer of the app. Assume We are planning to use Coroutine in an Activity or Fragment , We can use lifecycleScope to start the coroutine. In case of ViewModel, We can use the viewModelScope. Once the activity or View model life cycle is destroyed the coroutine will also be destroyed.
// Some examples of starting Coroutine with different scopeslifecycleScope.launch {} // Used in Activity/ Fragments
lifecycleScope.async {} // Used in Activity/ FragmentsviewModelScope.launch {} // Used in ViewModel
viewModelScope.async {}// Used in ViewModel
We can see that I have used launch and await to start the coroutine
launch — basic definition of launch is fire and forgot. Say we have scenario to upload logs to the server. In this case you can initiate the upload request and forgot about it.
async — It basically provides an callback once the operation is completed. we can wait for the response using await.
val result = viewModelScope.async {
// Some task
}
result.await()

We can see from the above image lifecycleScope.launch returns an Job.
On the other hand, lifecycleScope.async returns an Deferred<Unit>. By calling await with deferred result we can get the value once the coroutine completes its job. Logs after running the above code

To define the place of Where we want our coroutine to run, we can use Dispatchers. It determines the thread used by Coroutine for execution.
We have the following types of Dispatcher
Main- Used for UI operation
IO- Used for network or disk operation
Default- Used for CPU intensive task
These Dispatcher can be passed along with Coroutine Context in Coroutine Scope. If no Dispatcher is mentioned in the context it will assume Default.
lifecycleScope.launch(Dispatchers.IO) {}
Coroutines can also be cancelled. Just assign the result of Coroutine scope to an variable and invoke cancel function. This will cancel all the coroutine task running inside the coroutine.
We also have Job and Supervisor Job in Coroutines. This controls the lifecycle of an Coroutine. In default, Assume an Coroutine has multiple Childs. Once Child task fails with some exceptions this will stop all the subsequent child tasks but we can avoid such scenario’s using Supervisor Job. In this case once a child fail this will not affect the other coroutines running the job.
Thanks for reading..