📖 Scenario: You are building a simple Kotlin program that uses Flow to emit numbers. You want to understand how the context (like the dispatcher) is preserved when collecting the flow.
🎯 Goal: Create a Flow that emits numbers, configure a coroutine context variable, collect the flow preserving the context, and print the results.
📋 What You'll Learn
Create a Flow that emits numbers 1 to 3
Create a coroutine context variable using Dispatchers.Default
Collect the flow using flowOn to preserve the context
Print each emitted number inside the collector
💡 Why This Matters
🌍 Real World
Flows are used in Kotlin to handle streams of data asynchronously, such as user inputs, network responses, or sensor data.
💼 Career
Understanding flow context preservation is important for writing efficient and correct asynchronous Kotlin applications, especially in Android development and backend services.
Progress0 / 4 steps
1
Create a Flow emitting numbers 1 to 3
Create a Flow called numberFlow that emits the numbers 1, 2, and 3 using flow builder and emit.
Kotlin
Hint
Use val numberFlow: Flow = flow { emit(1); emit(2); emit(3) } to create the flow.
2
Create a coroutine context variable
Create a variable called context and set it to Dispatchers.Default.
Kotlin
Hint
Use val context = Dispatchers.Default to create the context variable.
3
Collect the flow preserving the context
Use flowOn(context) on numberFlow and collect it inside a runBlocking block. Use collect with a lambda that takes value and prints it with println.
Kotlin
Hint
Use runBlocking { numberFlow.flowOn(context).collect { value -> println(value) } } to collect and print.
4
Print the collected values
Run the program and print the output of collecting numberFlow with flowOn(context). The output should be the numbers 1, 2, and 3 each on its own line.
Kotlin
Hint
Run the program. You should see 1, 2, and 3 printed each on its own line.
Practice
(1/5)
1. What does flowOn do in Kotlin Flow context preservation?
easy
A. It converts a flow into a list.
B. It cancels the flow immediately.
C. It collects the flow on the main thread only.
D. It changes the coroutine context where the flow is executed.
Solution
Step 1: Understand flowOn purpose
flowOn switches the coroutine context for upstream flow operations.
Step 2: Identify effect on execution
It changes the thread or dispatcher where the flow runs, preserving context safely.
Final Answer:
It changes the coroutine context where the flow is executed. -> Option D
A. Multiple flowOn calls cause context override; only the last applies upstream.
B. flowOn cannot be used with runBlocking.
C. emit must be called inside collect block.
D. Dispatchers.Default is not a valid dispatcher.
Solution
Step 1: Understand flowOn chaining behavior
Multiple flowOn calls override upstream context; only the nearest upstream applies.
Step 2: Identify effect on this code
The second flowOn(Dispatchers.Default) overrides the first flowOn(Dispatchers.IO), so emission runs on Default, not IO.
Final Answer:
Multiple flowOn calls cause context override; only the last applies upstream. -> Option A
Quick Check:
Multiple flowOn = last one wins [OK]
Hint: Only one flowOn affects upstream; last one wins [OK]
Common Mistakes:
Thinking flowOn can be used multiple times independently
Believing emit must be inside collect
Assuming Dispatchers.Default is invalid
5. You want to perform a CPU-intensive calculation inside a flow without blocking the main thread, then update UI on the main thread. Which is the best way to preserve flow context?
hard
A. Perform calculation inside collect block on main thread.
B. Use flowOn(Dispatchers.Default) for calculation, then collect on main thread.
C. Use flowOn(Dispatchers.Main) for calculation, then collect on IO thread.
D. Use flowOn(Dispatchers.IO) for calculation, then collect on Default dispatcher.
Solution
Step 1: Identify dispatcher for CPU-intensive work
CPU-intensive tasks should run on Dispatchers.Default to avoid blocking main thread.
Step 2: Preserve UI update on main thread
Collecting on main thread allows safe UI updates after calculation.
Final Answer:
Use flowOn(Dispatchers.Default) for calculation, then collect on main thread. -> Option B
Quick Check:
CPU work on Default, UI update on Main [OK]
Hint: CPU work on Default dispatcher, collect on Main thread [OK]
Common Mistakes:
Running CPU work on Main dispatcher blocking UI
Collecting on background thread causing UI errors
Using IO dispatcher for CPU-intensive tasks
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.