suspend function in Kotlin Coroutines
- Authors
- Name
- Amit Shekhar
- Published on
I am Amit Shekhar, Co-Founder @ Outcome School, I have taught and mentored many developers, and their efforts landed them high-paying tech jobs, helped many tech companies in solving their unique problems, and created many open-source libraries being used by top companies. I am passionate about sharing knowledge through open-source, blogs, and videos.
Join Outcome School and get high paying tech job: Outcome School
Before we start, I would like to mention that, I have released a video playlist to help you crack the Android Interview: Check out Android Interview Questions and Answers.
In this blog, we will learn about the suspend function in Kotlin Coroutines.
Let's get started.
The definition of suspend function:
Suspend function is a function that could be started, paused, and resume.
What exactly does it mean?
The below image tells more about it.
functionA
was running.functionA
was suspended after some time.- While the
functionA
was suspended,functionB
started running and finished its work. - Then again,
functionA
started running.
Now, the question is how does it work.
How does the suspend function work?
For that, we need to discuss a little about the Coroutines. If you are interested in mastering the Kotlin Coroutines, learn from here.
Coroutines = Co + Routines
Here, Co means cooperation and Routines means functions.
It means that when functions cooperate with each other, we call it as Coroutines.
Let's understand this with an example. I have written the below code in a different way just for the sake of understanding. Suppose we have two functions as functionA
and functionB
.
functionA
as below:
fun functionA(case: Int) {
when (case) {
1 -> {
taskA1()
functionB(1)
}
2 -> {
taskA2()
functionB(2)
}
3 -> {
taskA3()
functionB(3)
}
4 -> {
taskA4()
functionB(4)
}
}
}
And functionB
as below:
fun functionB(case: Int) {
when (case) {
1 -> {
taskB1()
functionA(2)
}
2 -> {
taskB2()
functionA(3)
}
3 -> {
taskB3()
functionA(4)
}
4 -> {
taskB4()
}
}
}
Then, we can call the functionA
as below:
functionA(1)
Here, functionA
will do the taskA1
and give control to the functionB
to execute the taskB1
.
Then, functionB
will do the taskB1
and give the control back to the functionA
to execute the taskA2
and so on.
The important thing is that functionA
and functionB
are cooperating with each other.
It has given us the power: Execute a few lines of functionA
and then execute a few lines of functionB
and then again a few lines of functionA
and so on.
With Kotlin Coroutines, the above cooperation can be done very easily which is without the use of when or switch case which I have used in the above example for the sake of understanding.
Here comes, the suspend keyword in the picture. When we add the suspend keyword in the function, all the cooperations are automatically done for us. We don't have to use when or switch case. When we write like below:
suspend fun doSomething(request: Request): Response {
// do something
}
Internally, it gets converted by the compiler to another function without the suspend keyword with an extra parameter of the type Continuation
like below:
fun doSomething(request: Request, continuation: Continuation)...
The Continuation<T>
is an interface which looks like below(taken from Kotlin source code):
public interface Continuation<in T> {
public val context: CoroutineContext
public fun resumeWith(result: Result<T>)
}
In addition to that, it has two extension functions.
fun <T> Continuation<T>.resume(value: T)
fun <T> Continuation<T>.resumeWithException(exception: Throwable)
If you notice the functions closely, they can be used to resume the coroutine with a return value or with an exception if an error had occurred while the function was suspended.
This way, a function could be started, paused, and resume with the help of Continuation. We just have to use the suspend keyword.
Note: Suspend functions are only allowed to be called from a coroutine or another suspend function. You can see that the async function which includes the keyword suspend. So, in order to use that, we need to make our function suspend too.
Let's take a very standard use-case of an Android Application which is as follows:
- Fetch User from the server.
- Show the User in the UI.
suspend fun fetchUser(): User {
return withContext(Dispatchers.IO) {
// make network call
// return user
}
}
fun showUser(user: User) {
// show user
}
Note: If you are using the 3rd party networking library that makes the network call on background thread by default, in that case, no need to use withContext(Dispatchers.IO)
. We can skip that part to just write like below:
suspend fun fetchUser(): User {
// make network call
// return user
}
So, the suspend function fetchUser
can only be called from another suspend function or a coroutine. We can't make the onCreate function of an activity suspend, so we need to call it from the coroutines like below:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
GlobalScope.launch(Dispatchers.Main) {
val user = fetchUser() // fetch on IO thread
showUser(user) // back on UI thread
}
}
fetchUser
will run on the IO thread for making the network call.
Only when the fetching of the user is completed, showUser
will get called.
showUser
will run on UI thread because we have used the Dispatchers.Main to launch it.
Now, we know what is suspend function, how does it work.
Show your love by sharing this blog with your fellow developers.
Prepare yourself for Android Interview: Android Interview Questions
That's it for now.
Thanks
Amit Shekhar
Co-Founder @ Outcome School
You can connect with me on:
Follow Outcome School on: