We use withContext to switch the thread or dispatcher in Kotlin coroutines. It helps run code on the right thread, like doing heavy work in the background and updating UI on the main thread.
WithContext for dispatcher switching in Kotlin
suspend fun someFunction() { withContext(Dispatchers.IO) { // code to run on this dispatcher } }
withContext is a suspend function, so it must be called from a coroutine or another suspend function.
You pass a dispatcher like Dispatchers.IO or Dispatchers.Main to tell where the code should run.
withContext(Dispatchers.IO) {
// run blocking IO task here
}withContext(Dispatchers.Main) {
// update UI here
}val result = withContext(Dispatchers.Default) { // do CPU heavy work 42 }
This program starts on the main thread, switches to IO dispatcher to simulate loading data, then switches back to the main thread to print the result.
import kotlinx.coroutines.* fun main() = runBlocking { println("Start on thread: ${Thread.currentThread().name}") val data = withContext(Dispatchers.IO) { println("Working on thread: ${Thread.currentThread().name}") // Simulate slow IO task delay(500) "Data loaded" } println("Back on thread: ${Thread.currentThread().name}") println("Result: $data") println("End on thread: ${Thread.currentThread().name}") }
Always use withContext inside a coroutine or suspend function.
Switching dispatchers helps keep your app responsive and avoids freezing the screen.
Common dispatchers are Dispatchers.Main for UI, Dispatchers.IO for input/output, and Dispatchers.Default for CPU work.
withContext lets you run code on a specific thread or dispatcher inside coroutines.
Use it to keep your app smooth by moving heavy work off the main thread.
Remember to call it only from suspend functions or coroutines.
Practice
withContext in Kotlin coroutines?Solution
Step 1: Understand what
withContextdoeswithContextis used to change the dispatcher or thread where a coroutine runs, allowing you to move work to a background thread or back to the main thread.Step 2: Compare options with this purpose
Only To switch the coroutine execution to a different dispatcher or thread correctly describes switching execution context. Options A, C, and D describe other coroutine features.Final Answer:
To switch the coroutine execution to a different dispatcher or thread -> Option AQuick Check:
withContext switches dispatcher = B [OK]
- Confusing withContext with launching new coroutines
- Thinking it cancels coroutines
- Assuming it only runs on the main thread
withContext?Solution
Step 1: Recall the correct dispatcher name
The dispatcher for IO operations isDispatchers.IOwith uppercase IO.Step 2: Check syntax correctness
withContext(Dispatchers.IO) { /* code */ } uses the correct syntax:withContext(Dispatchers.IO) { ... }. Options B and C have wrong casing or order, and A incorrectly uses parentheses after IO.Final Answer:
withContext(Dispatchers.IO) { /* code */ } -> Option DQuick Check:
Correct dispatcher syntax = D [OK]
- Using lowercase 'io' instead of 'IO'
- Adding parentheses after dispatcher name
- Swapping Dispatchers and IO order
import kotlinx.coroutines.*
suspend fun main() = coroutineScope {
println("Start on: ${'$'}{Thread.currentThread().name}")
withContext(Dispatchers.Default) {
println("Inside withContext on: ${'$'}{Thread.currentThread().name}")
}
println("End on: ${'$'}{Thread.currentThread().name}")
}Solution
Step 1: Identify the starting thread
The main coroutine starts on the main thread, so the first print shows "main" thread.Step 2: Understand withContext dispatcher switch
ThewithContext(Dispatchers.Default)block runs on a background thread named like "DefaultDispatcher-worker-1".Step 3: Check thread after withContext
After the block, execution returns to the main thread, so the last print shows "main" again.Final Answer:
Start on: main Inside withContext on: DefaultDispatcher-worker-1 End on: main -> Option CQuick Check:
withContext switches thread temporarily = C [OK]
- Assuming thread stays switched after withContext
- Thinking withContext runs on main thread always
- Confusing coroutineScope with launch
withContext:
fun fetchData() {
withContext(Dispatchers.IO) {
println("Fetching data")
}
}Solution
Step 1: Check usage rules of withContext
withContextis a suspend function and must be called from a suspend function or coroutine.Step 2: Analyze fetchData function signature
fetchData is a regular function withoutsuspend, so callingwithContextinside it causes a compile error.Final Answer:
Missing suspend modifier on fetchData function -> Option BQuick Check:
withContext requires suspend function = A [OK]
- Forgetting to mark function as suspend
- Thinking dispatcher name is wrong
- Assuming withContext can be called anywhere
withContext to achieve this?Solution
Step 1: Identify correct dispatcher for heavy computation
Heavy computation should run onDispatchers.Defaultto avoid blocking the main thread.Step 2: Identify correct dispatcher for UI update
UI updates must happen onDispatchers.Mainto safely interact with the UI.Step 3: Check function signature and order
The function must be suspend to callwithContext. suspend fun process() { withContext(Dispatchers.Default) { // heavy computation } withContext(Dispatchers.Main) { // update UI } } correctly uses suspend and switches dispatchers in the right order.Final Answer:
suspend fun process() { withContext(Dispatchers.Default) { // heavy computation } withContext(Dispatchers.Main) { // update UI } } -> Option AQuick Check:
Heavy work on Default, UI on Main = A [OK]
- Running heavy work on Main thread
- Updating UI off the Main thread
- Not marking function as suspend
Ready to prove it?
Pass the test and this pattern moves unknown
