Open In App

Suspend Function In Kotlin Coroutines

Improve
Improve
Like Article
Like
Save
Share
Report

Prerequisite: Kotlin Coroutines on Android

The Kotlin team defines coroutines as “lightweight threads”. They are sort of tasks that the actual threads can execute. Coroutines were added to Kotlin in version 1.3 and are based on established concepts from other languages. Kotlin coroutines introduce a new style of concurrency that can be used on Android to simplify async code.

The official documentation says that coroutines are lightweight threads. By lightweight, it means that creating coroutines doesn’t allocate new threads. Instead, they use predefined thread pools and smart scheduling for the purpose of which task to execute next and which tasks later.

Suspend Function In Kotlin

Suspend function is a function that could be started, paused, and resume. One of the most important points to remember about the suspend functions is that they are only allowed to be called from a coroutine or another suspend function. An example is given below, in which we have tried to call the delay() function from outside of the coroutine.

Kotlin




// sample kotlin program to show use of delay function
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
          
        // will throw a error
        delay(1000L)
          
        GlobalScope.launch{
         // delay function (a suspend function) must called within coroutine
         // or another suspend function
        
    }
}


As we have called the delay function from outside of the coroutine, it will throw the error as below:

On hovering over the delay function we can see the error.

Delay Function

It is represented as delay(), It is a suspend function which delays coroutine for a given time without blocking a thread, and resumes it after a specified time. 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 cases in order to switch from one function to another. Let’s take an example of suspend function as:

Kotlin




// arbitrary do task function for explanation
suspend fun dotask(request: Request): Response
{
  // perform the task
}


Though it seems that only one argument has passed to dotask() function, but internally there are two arguments. Internally, it gets converted by the compiler to another function without the suspend keyword with an extra parameter of the type Continuation<T> like below:

Kotlin




// internal conversion of suspend function dotask()
fun dotask(request: Request, continuation: Continuation)...


The way suspend functions communicate with each other is with Continuation objects. A Continuation is just a generic callback interface with some extra information, which looks like below(taken from Kotlin source code):

Kotlin




// Continuation interface structure
public interface Continuation<in T>
{
  public val context: CoroutineContext
  public fun resumeWith(result: Result<T>)
}


  • context will be the CoroutineContext to be used in that continuation.
  • resumeWith resumes execution of the coroutine with a Result, that can contain either a value which is the result of the computation that caused the suspension or an exception.

Note: From Kotlin 1.3 onwards, you can also use the extension functions resume(value: T) and resumeWithException(exception: Throwable) which are specialized versions of the resumeWith call.

The two extension functions of resumeWith are given by:

  1. fun <T> Continuation<T>.resume(value: T)
  2. fun <T> Continuation<T>.resumeWithException(exception: Throwable)

We can see the two extension function that they can be used to resume the coroutines 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.

Kotlin




// Kotlin Program to demonstrate use of suspend function
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
          
          GlobalScope.launch{
          val networkCallAnswer==doNetworkCall()
          Log.d("Main-Activity,networkCallAnswer)
        
    }
      
    suspend fun doNetworkCall():String {
    delay(2000L);
    return "Network Call Answer"
    }               
}


We get the Log output after a delay of 2 seconds, since we have called doNetworkCall() from a coroutine, we have to make doNetworkCall() function as suspend.



Last Updated : 10 Sep, 2020
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads