Coroutines are a new emerging concept for modern software development. But the majority of developer concepts or we can say internal of coroutine are pretty unfamiliar. For most developers, coroutine works like magic, but there is no magic.
To use coroutines, we don't have to understand how coroutines work. We can just use them.
Most of us started learning software development with language like JAVA, where the concept of coroutine simply doesn't exist. What we did learn, however, was classes, functions, and interface works. Over time we developed a fundamental understanding of these concepts. We need some kind of understanding of the coroutine as well. This will help us to use coroutines correctly and efficiently.
How is it possible that with coroutine we can write code that can be suspended and resumed at a later point in time?
To answer the above question, let's first talk about how the Kotlin Build Process works for Android applications
We write the Kotlin code in the file with the extension .kt, As we know Kotlin is a compiled language therefore Kotlin files get compiled with the Kotlin compiler to the class file. This class file is also called JVM bytecode. Android build process takes the generated class file and packages them together with other resources to the APK file
Actual magic happens inside Kotlin Compiler
The coroutines that we write, after compilation converted into some other code style
Let's take an example of below code snippet
fun postItem(item:Item){
val token = requestToken()
val post = creatPost(token,item)
processPost(post)
}
In the above method, we take the item
as an input parameter, which contains the data that the user has to post. To post or process the item, first, we call requestToken
which will give a token
to call createPost
API and then after a success, we will have the post
ready. Last, we call the processPost
method which will process the post.
The above code style is called Direct Style
Direct Style
The code is called direct style when we have some action (e.g. requestToken
) from that we want to get a result(e.g. token
) that we have to wait for. And there is something else that we do after that action (e.g. createPost
and processPost
) is called continuation. In short in direct style code, we write action and their continuations sequentially.
Continuation Passing Style(CPS)
The code is called CPS when Instead of writing actions and their continuations sequentially, we pass continuations as a parameter to the actions.
fun postItem(item:Item){
requestToken { token->
creatPost(token,item) { post ->
processPost(post)
}
}
}
CPS is just a fancy name for Callbacks
To solve the logical problem where we have to call some actions and then wait for the result before proceeding to their continuation we have to write the code in CPS style(in the form of callbacks). Following this coding style can lead to a Callback Hell Problem
Callback Hell is essentially nested callbacks stacked below one another forming a pyramid structure. Every callback depends/waits for the previous callback, thereby making a pyramid structure that affects the readability and maintainability of the code
Coroutine lets us write CPS style code to Direct Style
suspend fun postItem(item:Item){
val token = requestToken()
val post = creatPost(token,item)
processPost(post)
}
Then kotlin compiler converts the Direct Style code after compilation. We will discuss how this conversion happens in the next article