Kotlin coroutines are lightweight units of concurrency that simplify asynchronous programming. They allow multiple tasks to run efficiently without creating a separate thread for every task and can suspend and resume execution without blocking the underlying thread.
- Coroutines are lightweight because creating them does not require creating a new thread for every task.
- They efficiently use existing threads and scheduling mechanisms to execute tasks.
- Coroutines simplify asynchronous programming, especially in Android applications.
Suspend Function In Kotlin
A suspend function is a function marked with the suspend keyword that can suspend its execution at a suspension point and resume later without blocking the underlying thread. A suspend function can only be called from another suspend function or from within a coroutine.
Calling a Suspend Function Inside a Coroutine:
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// delay(1000L)
// Error: delay() cannot be called directly here
lifecycleScope.launch {
// delay() can be called inside a coroutine
delay(1000L)
}
}
}
Explanation:
- delay() is a suspend function that suspends the coroutine without blocking the underlying thread.
- Calling delay() directly inside onCreate() causes an error because onCreate() is neither a suspend function nor a coroutine.
- lifecycleScope.launch creates a coroutine, allowing suspend functions such as delay() to be called inside it.
Delay Function
The delay() function is a commonly used suspend function in Kotlin Coroutines. It suspends a coroutine for a specified period without blocking the underlying thread and resumes execution after the delay is complete.
delay()suspends only the coroutine, not the thread.- Other coroutines can continue executing while one coroutine is delayed.
- It is commonly used for non-blocking delays in asynchronous operations.
Syntax of a Suspend Function
A function is declared as a suspend function by adding the suspend keyword before the fun keyword.
suspend fun doTask(request: Request): Response {
// Perform the required task
}
Suspend functions can call other suspend functions and may suspend their execution at suspension points.
How Suspend Functions Work
When a coroutine reaches a suspension point, such as delay(), the coroutine can suspend its execution without blocking the thread. The underlying thread is then free to perform other work.
When the suspended operation is ready to continue, the coroutine resumes from the point where it was suspended. Kotlin manages this process internally using coroutine machinery.
Continuation in Kotlin
A continuation represents the state required to resume a suspended coroutine. Conceptually, it contains information about where the coroutine should continue and the context in which it should resume.
The Continuation interface includes the coroutine context and a method for resuming execution with a result or an exception.
- context provides the CoroutineContext associated with the continuation.
- resumeWith() resumes the continuation with either a successful result or an exception.
public interface Continuation<in T> {
public val context: CoroutineContext
public fun resumeWith(result: Result<T>)
}
Example: Using a Suspend Function
The following example demonstrates a suspend function being called from inside a coroutine:
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
lifecycleScope.launch {
val networkCallAnswer = doNetworkCall()
Log.d("MainActivity", networkCallAnswer)
}
}
suspend fun doNetworkCall(): String {
delay(2000L)
return "Network Call Answer"
}
}
Explanation
lifecycleScope.launchstarts a coroutine associated with the Activity lifecycle.doNetworkCall() is marked with suspend because it calls delay(), a suspend function that can only be called from a coroutine or another suspend function.delay(2000L)suspends the coroutine for 2 seconds without blocking the underlying thread.- After the delay, the coroutine resumes and returns
"Network Call Answer". - The returned value is displayed using
Log.d().