0
0
KotlinHow-ToBeginner · 3 min read

How to Switch Dispatcher in Coroutine in Kotlin

In Kotlin, you switch coroutine dispatchers using the withContext function, which changes the coroutine's context to a different CoroutineDispatcher. This lets you run code on different threads like Dispatchers.IO for background tasks or Dispatchers.Main for UI updates.
📐

Syntax

The withContext function is used to switch the coroutine dispatcher temporarily. It takes a CoroutineDispatcher as a parameter and a block of code to run on that dispatcher.

  • dispatcher: The target dispatcher like Dispatchers.IO, Dispatchers.Default, or Dispatchers.Main.
  • block: The code to execute on the specified dispatcher.
kotlin
suspend fun example() {
    withContext(Dispatchers.IO) {
        // Code here runs on IO dispatcher
    }
}
💻

Example

This example shows switching from the main dispatcher to the IO dispatcher to perform a background task, then back to the main dispatcher to update the UI.

kotlin
import kotlinx.coroutines.*

fun main() = runBlocking {
    println("Running on thread: ${Thread.currentThread().name}")

    withContext(Dispatchers.IO) {
        println("Running on IO thread: ${Thread.currentThread().name}")
        // Simulate background work
        delay(500)
    }

    println("Back to thread: ${Thread.currentThread().name}")
}
Output
Running on thread: main Running on IO thread: DefaultDispatcher-worker-1 Back to thread: main
⚠️

Common Pitfalls

One common mistake is trying to switch dispatchers without using withContext, which does not change the thread. Another is blocking the main thread with long-running tasks instead of switching to Dispatchers.IO.

Always use withContext inside a suspend function or coroutine scope to switch dispatchers properly.

kotlin
import kotlinx.coroutines.*

fun main() = runBlocking {
    // Wrong: This runs on the current dispatcher, no switch
    // Thread will be main here
    println("Before delay: ${Thread.currentThread().name}")
    delay(500) // Still main thread
    println("After delay: ${Thread.currentThread().name}")

    // Right: Switch to IO dispatcher
    withContext(Dispatchers.IO) {
        println("Inside IO dispatcher: ${Thread.currentThread().name}")
    }
}
Output
Before delay: main After delay: main Inside IO dispatcher: DefaultDispatcher-worker-1
📊

Quick Reference

Use this quick guide to remember dispatcher switching:

FunctionPurposeExample Dispatcher
withContext(dispatcher) { ... }Switch coroutine context temporarilyDispatchers.IO, Dispatchers.Main, Dispatchers.Default
Dispatchers.IOFor blocking IO tasks like file or networkwithContext(Dispatchers.IO) { ... }
Dispatchers.MainFor UI updates on main threadwithContext(Dispatchers.Main) { ... }
Dispatchers.DefaultFor CPU-intensive taskswithContext(Dispatchers.Default) { ... }

Key Takeaways

Use withContext to switch coroutine dispatchers safely and efficiently.
Dispatchers.IO is for background IO tasks; Dispatchers.Main is for UI work.
Always switch dispatchers inside suspend functions or coroutine scopes.
Avoid blocking the main thread by switching to appropriate dispatchers.
withContext temporarily changes the coroutine's thread for the block of code.