What do i know about Coroutines (The basics)

Mohamed Rimshad
3 min readAug 2, 2022

--

Threading with Kotlin coroutines..

Let’s talk about threads first.

A thread of execution is a small chain of programmed instruction. This is usually managed by a scheduler, which is usually a part of an operating system. Ok, so that’s a thread.

Threading in Android.

As for Android, when an app launched, it creates the first thread of execution, which is the main thread. which is in charge for dispatching important things like events to UI widgets.

Need of threading in Android

  1. To avoid overusing the main thread and keep our app responsive.(although some of the operations are only allowed to run on different threads but not on the main thread)

Synchronous and Asynchronous executions.

synchronous means code is executed in a sequential/sequencial order. which means when 1 task is being executed, the next one will only be executed after this one is finished and so on. As for the Asynchronous, it will not wait for one execution to be finished but will be moved into another one even before finishing the previous one. Simply synchronous tasks are dependent while Asynchronous are not.

In synchronous execution, if we have a background task running on the main thread, it could block the MAIN thread and freeze the UI. We don’t want that.

So the solution is to move all non-UI-related threads to a different thread.

Here Come Coroutines for Asynchronous programming.

To write a coroutine task or operation we need to call a particular coroutine scope. There are multiple coroutine scopes.

Choosing a CoroutineScope

To write a coroutine task or operation, we need to call a particular coroutine scope. There are multiple coroutine scopes.

  1. GlobalScope

This scope will stay alive as long as our app is not destroyed. and this is not bound to any other jobs. thus this scope can be used to run something on the whole application lifetime.

2. lifecycleScope

This scope will stay alive as long as our activity/fragment is not destroyed. and it will be cancelled when the activity/fragment is destroyed. Thus this scope can be used to run something on the whole activity lifetime.

3. viewModelScope

Defined in our ViewModel classes, only bound to ViewModel’s lifecycle and lives as long as ViewModel lives, it will be wise to use them if we have a work that needs to be done only if the ViewModel is active. so that when the ViewModel is dead and work will be cancelled and prevent them from consuming more resources.

4. rememberCoroutineScope

Used in Jetpack compose classes/activities, but as a composable function and can returns a CoroutineScope bound to the point of the Composition where it’s called.

Choosing Dispatchers.

Dispatchers are the contexts, this will determine on which thread pool the coroutines will run. There are 4 types of Dispatchers.

  1. Dispatchers.Default

For intense CPU works like sorting a list or complex calculations.

2. Dispatchers.Main

The must-have dispatcher for UI-based events such as updating an ImageView or TextView. UI events can only be run in this main thread.

3. Dispatchers.IO

For heavy and intense IO works. such as for long-running database queries or reading and writing from files.

4. Dispatchers.Unconfined

This one is not confined to any specific thread, a rarely used dispatcher. You can use this for something that’s not that heavy, but you want to run it on a different thread.

Some Samples

GlobalScope will be alive as long as the application is alive

GlobalScope.launch(Dispatchers.Default){
//your task
executeOrder66()
}
GlobalScope.launch(Dispatchers.IO) {
//your task
searchForTraitors()
}
GlobalScope.launch(Dispatchers.Main) {
//your task
updateJediPictures()
}

lifecyclescope will be alive as long as the activity is alive

lifecycleScope.launch(Dispatchers.Default){
//your task
findNemo()
}
lifecycleScope.launch(Dispatchers.IO){
//your task
searchForNemo()
}
lifecycleScope.launch(Dispatchers.Main){
//your task
updateNemoPicture()
}

You know you can add delays in any coroutineScopes, and ViewModelScopes will be alive as long as the ViewModel is active.

viewModelScope.launch(Dispatchers.Default){
//your task
delay(2000)
findPrivateRyan()
}
viewModelScope.launch(Dispatchers.IO){
delay(3000)
//your task
SavePrivateRyan()
}
viewModelScope.launch(Dispatchers.Main){
delay(5000)
//your task
BringPrivateRyan()
}

Thus you can run your tasks in different threads,

We cannot wind up this without mentioning Suspend functions and Kotlin Flows, but that will come in another part. Ciao….

--

--