Suspend Function In Kotlin Coroutines

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

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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
        
    }
}

chevron_right


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

filter_none

edit
close

play_arrow

link
brightness_4
code

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

chevron_right


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

filter_none

edit
close

play_arrow

link
brightness_4
code

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

chevron_right


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

filter_none

edit
close

play_arrow

link
brightness_4
code

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

chevron_right


  • 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

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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"
    }               
}

chevron_right


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.




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.


Article Tags :
Practice Tags :


4


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.