Kotlin Coroutines

Filed Under: Kotlin

In this tutorial, we’ll be looking into Kotlin Coroutines. Coroutines is a vital concept since asynchronous programming is the way to go over the traditional blocking a thread and polling stuff.

Kotlin Coroutines

Concurrency is vital in programming. Running different tasks on different threads. But sometimes, we as developers can get carried away and create too many Thread objects which would eventually consume a lot of memory and time. Thankfully, Kotlin has introduced Coroutines which are light-weight threads.

By light-weight threads we mean, Coroutines take less memory and time compared with the default Java threads.
Coroutines though currently in the initial stages only, has a powerful set of libraries which we can use to make the computation stuff easy.

Coroutines computations can be done without blocking other threads.

How?

Suspending Functions is the answer to it.

Suspending functions are introduced with Coroutines and allow us to start the function from where it left off. This aids further in memory optimizations of the CPU and multi-tasking.

Unlike blocking a thread, suspending functions are less expensive and do not require a context switching.

A suspending function can be created by adding the modifier suspend to a function.


suspend fun helloSuspend(){
println("Hello Suspending Functions")
}

A suspending function can be only called from a coroutine or another suspending function.
Coroutine comes up with some popular Coroutine Builders to start a coroutine:

  • launch: This creates a new coroutine. It just fires and forgets. Doesn’t wait for the response. If an exception occurs, it’s an uncaught exception that would abrupt the program flow.
  • async: This fires and waits for the response. The response is of the type
  • Deferred<T>. To get the response we invoke await on the function.
  • runBlocking – This is similar to launch except that inside a runblocking everything would be on the same coroutine.
  • run – This is a basic coroutine.
await is a suspending function.

The equivalent for Thread.sleep is delay function.


import kotlinx.coroutines.experimental.CommonPool
import kotlinx.coroutines.experimental.delay
import kotlinx.coroutines.experimental.launch


suspend fun helloSuspend(){
    println("Hello Suspending Functions")
}

fun main(args: Array<String>) {
    println("Start")
    launch(CommonPool) {
        delay(2000)
        helloSuspend()
        println("Inside launch")
    }
    println("Finished")
    //helloSuspend() //this won't compile
}

The output of the above code is:
kotlin coroutines

The helloSuspend method isn’t run since the function just fires and forgets.

We use the join function which waits for the completion.


import kotlinx.coroutines.experimental.*


suspend fun helloSuspend() {
    println("Hello Suspending Functions")
}

fun main(args: Array<String>) = runBlocking {
    println("Start")
    val x = launch(CommonPool) {
        delay(2000)
        helloSuspend()
        println("Inside launch")
    }
    println("Finished")
    x.join()

}

The output now is:
kotlin coroutines example

We’ve used a runBLocking function as the root coroutine since join is a suspending function and it cannot be invoked outside a coroutine/suspending function.


import kotlinx.coroutines.experimental.*


suspend fun helloSuspend() {
    println("Hello Suspending Functions")
}

fun main(args: Array<String>) = runBlocking {
    println("Start")
    val x = async(CommonPool) {
        delay(2000)
        helloSuspend()
        println("Inside async")
    }

    x.await()
    println("Finished")

}
Difference between join and await.
join waits for completion of launch.

await looks for the returned result.


import kotlinx.coroutines.experimental.*

suspend fun helloSuspend() {
    println("Hello Suspending Functions")
}

fun main(args: Array<String>) = runBlocking {
    println("Start")
    val x = async(CommonPool) {
        delay(2000)
        helloSuspend()
        println("Inside async")
    }

    x.await()
    println("Finished")
    
    run{
        println("Inside run")
    }

}

//print
//Start
//Hello Suspending Functions
//Inside async
//Finished
//Inside run

In the following section, in our IntellIJ we’ll be creating an application using Coroutines that fetches url data asynchronously.

Create a new Gradle Project in your IntelliJ:
kotlin coroutines project

In your build.gradle add the following dependencies:


compile 'org.jetbrains.kotlinx:kotlinx-coroutines-core:0.22.5'
compile 'khttp:khttp:0.1.0'

Add this block too:


kotlin {
    experimental {
        coroutines "enable"
    }
}

You build.gradle should look like this:

kotlin coroutines gradle

Create a new Kotlin file in the Kotlin folder.
IN the following code, we fetch the url’s content through an async coroutine.


import kotlinx.coroutines.experimental.CommonPool
import kotlinx.coroutines.experimental.async
import kotlinx.coroutines.experimental.launch
import kotlinx.coroutines.experimental.runBlocking


suspend fun fetch(url: String): String {
    return khttp.get(url).text
}

fun main(args: Array<String>) = runBlocking {

    val job = async(CommonPool) {
        var x = fetch("https://www.journaldev.com")
        print(x)
    }
    val x = launch(CommonPool) {
        job.await()
    }

    x.join()


}

In the above code, fetch is a suspending function that’s called inside an async coroutine. await is used to get the return value of the coroutine.
join finally waits for the completion of the coroutine.

Following is the output:
kotlin coroutines

That’s all for Kotlin Coroutines example tutorial.

Reference: API Doc

Leave a Reply

Your email address will not be published. Required fields are marked *

close
Generic selectors
Exact matches only
Search in title
Search in content
Search in posts
Search in pages