Bird
Raised Fist0
Kotlinprogramming~20 mins

FlowOn for changing dispatcher in Kotlin - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
FlowOn Mastery
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
What is the output of this Kotlin Flow code with flowOn?

Consider the following Kotlin code using flowOn. What will be printed?

Kotlin
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*

fun main() = runBlocking {
    flow {
        println("Emitting on thread: ${Thread.currentThread().name}")
        emit(1)
    }
    .flowOn(Dispatchers.Default)
    .collect {
        println("Collected $it on thread: ${Thread.currentThread().name}")
    }
}
A
Emitting on thread: DefaultDispatcher-worker-1
Collected 1 on thread: DefaultDispatcher-worker-1
B
Emitting on thread: main
Collected 1 on thread: DefaultDispatcher-worker-1
C
Emitting on thread: main
Collected 1 on thread: main
D
Emitting on thread: DefaultDispatcher-worker-1
Collected 1 on thread: main
Attempts:
2 left
💡 Hint

Remember that flowOn changes the dispatcher of the upstream flow emissions.

🧠 Conceptual
intermediate
1:30remaining
Which statement about flowOn is correct?

Choose the correct statement about flowOn in Kotlin Flow.

A<code>flowOn</code> delays the flow emissions by switching dispatcher after collection.
B<code>flowOn</code> cancels the flow if the dispatcher is not specified.
C<code>flowOn</code> changes the dispatcher only for the upstream flow emissions.
D<code>flowOn</code> changes the dispatcher of the entire flow including collection.
Attempts:
2 left
💡 Hint

Think about which part of the flow flowOn affects.

🔧 Debug
advanced
2:00remaining
Why does this flowOn usage cause a runtime error?

Examine the code below. Why does it throw an exception at runtime?

Kotlin
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*

fun main() = runBlocking {
    flow {
        emit(1)
    }
    .flowOn(Dispatchers.IO)
    .collect {
        delay(1000)
        println(it)
    }
}
ABecause delay cannot be called inside collect without a suspend function.
BBecause delay inside collect is allowed, no runtime error occurs.
CBecause flowOn cannot be used with Dispatchers.IO.
DBecause collect is blocking and delays the flow emission causing deadlock.
Attempts:
2 left
💡 Hint

Recall that collect is a suspend function and can call delay.

❓ Predict Output
advanced
2:30remaining
What is the output of this flow with multiple flowOn calls?

What will this Kotlin program print?

Kotlin
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*

fun main() = runBlocking {
    flow {
        println("Start emitting on: ${Thread.currentThread().name}")
        emit(1)
    }
    .flowOn(Dispatchers.IO)
    .map {
        println("Mapping $it on: ${Thread.currentThread().name}")
        it * 2
    }
    .flowOn(Dispatchers.Default)
    .collect {
        println("Collected $it on: ${Thread.currentThread().name}")
    }
}
A
Start emitting on: IO-thread
Mapping 1 on: DefaultDispatcher-worker-1
Collected 2 on: main
B
Start emitting on: DefaultDispatcher-worker-1
Mapping 1 on: DefaultDispatcher-worker-2
Collected 2 on: main
C
Start emitting on: main
Mapping 1 on: IO-thread
Collected 2 on: DefaultDispatcher-worker-1
D
Start emitting on: IO-thread
Mapping 1 on: IO-thread
Collected 2 on: main
Attempts:
2 left
💡 Hint

Remember each flowOn affects upstream operators only.

🧠 Conceptual
expert
2:00remaining
How does flowOn affect upstream and downstream operators in a flow chain?

Given a flow chain with multiple operators and flowOn calls, which statement is true?

A<code>flowOn</code> changes the dispatcher of all operators upstream from its position.
B<code>flowOn</code> changes the dispatcher of all operators downstream from its position.
C<code>flowOn</code> changes the dispatcher of the operator immediately before it only.
D<code>flowOn</code> changes the dispatcher of the entire flow regardless of position.
Attempts:
2 left
💡 Hint

Think about the direction of data flow and which operators flowOn affects.

Practice

(1/5)
1. What does the flowOn operator do in Kotlin Flow?
easy
A. It collects the flow on the main thread.
B. It changes the thread where the flow is executed.
C. It cancels the flow immediately.
D. It buffers the flow emissions.

Solution

  1. Step 1: Understand the role of flowOn

    The flowOn operator changes the dispatcher where the upstream flow runs, allowing background work on a different thread.
  2. Step 2: Differentiate from other flow operators

    Unlike collection which runs on the original coroutine context, flowOn switches the execution context of the flow itself.
  3. Final Answer:

    It changes the thread where the flow is executed. -> Option B
  4. Quick Check:

    flowOn switches thread = B [OK]
Hint: Remember: flowOn changes flow thread, not collector thread [OK]
Common Mistakes:
  • Confusing flowOn with collect context
  • Thinking flowOn cancels the flow
  • Assuming flowOn buffers emissions
2. Which of the following is the correct syntax to apply flowOn to a flow named myFlow to run on Dispatchers.IO?
easy
A. myFlow.runOn(Dispatchers.IO)
B. myFlow.collectOn(Dispatchers.IO)
C. myFlow.flow(Dispatchers.IO)
D. myFlow.flowOn(Dispatchers.IO)

Solution

  1. Step 1: Identify the correct function name

    The operator to change the dispatcher of a flow is flowOn, not collectOn, flow, or runOn.
  2. Step 2: Confirm the syntax usage

    The correct syntax is calling flowOn on the flow instance with the dispatcher as argument.
  3. Final Answer:

    myFlow.flowOn(Dispatchers.IO) -> Option D
  4. Quick Check:

    Correct syntax = A [OK]
Hint: Use flowOn exactly as method name [OK]
Common Mistakes:
  • Using wrong method names like collectOn
  • Passing dispatcher incorrectly
  • Confusing flowOn with collect
3. What will be the output thread of the collector in this code snippet?
flow {
  emit(Thread.currentThread().name)
}.flowOn(Dispatchers.IO)
 .collect { println(it) }
medium
A. The collector runs on the original coroutine context thread.
B. The collector runs on the main thread regardless.
C. The collector runs on Dispatchers.IO thread.
D. The collector runs on a new thread created by flowOn.

Solution

  1. Step 1: Understand flowOn effect on upstream

    The flowOn(Dispatchers.IO) changes the thread where the flow builder runs, so emit runs on IO thread.
  2. Step 2: Identify collector thread context

    The collector runs on the coroutine context where collect is called, which is the original coroutine context unless changed explicitly.
  3. Final Answer:

    The collector runs on the original coroutine context thread. -> Option A
  4. Quick Check:

    Collector thread = original context = C [OK]
Hint: flowOn changes upstream thread, collector stays on original [OK]
Common Mistakes:
  • Assuming collector runs on flowOn dispatcher
  • Thinking flowOn creates new thread for collector
  • Confusing emit thread with collect thread
4. Identify the error in this Kotlin Flow code:
flow {
  emit(1)
}.flowOn(Dispatchers.IO)
.collect { value ->
  println(value)
}
medium
A. Missing coroutine scope to call collect.
B. flowOn cannot be used with emit.
C. collect must be called before flowOn.
D. Dispatchers.IO is not a valid dispatcher.

Solution

  1. Step 1: Check coroutine context for collect

    The collect function is a suspend function and must be called inside a coroutine or suspend function.
  2. Step 2: Verify flowOn and emit usage

    Using flowOn(Dispatchers.IO) with emit is correct; no error here.
  3. Final Answer:

    Missing coroutine scope to call collect. -> Option A
  4. Quick Check:

    collect needs coroutine scope = D [OK]
Hint: Always call collect inside coroutine or suspend function [OK]
Common Mistakes:
  • Thinking flowOn can't be used with emit
  • Calling collect outside coroutine
  • Misordering flowOn and collect
5. You want to perform a CPU-intensive calculation inside a flow and collect results on the main thread. Which is the correct way to use flowOn and collect to achieve this?
hard
A. Use collectOn(Dispatchers.Default) for calculation and flowOn(Dispatchers.Main) for collection.
B. Use flowOn(Dispatchers.Main) for calculation and collect on Default dispatcher.
C. Use flowOn(Dispatchers.Default) for calculation and collect on main thread.
D. Run calculation and collection both on Dispatchers.IO.

Solution

  1. Step 1: Choose dispatcher for CPU-intensive work

    CPU-intensive tasks should run on Dispatchers.Default to avoid blocking main thread.
  2. Step 2: Use flowOn to switch flow execution thread

    Applying flowOn(Dispatchers.Default) runs the flow builder on Default dispatcher.
  3. Step 3: Collect on main thread

    Collecting on main thread allows UI updates; no dispatcher change needed for collect.
  4. Final Answer:

    Use flowOn(Dispatchers.Default) for calculation and collect on main thread. -> Option C
  5. Quick Check:

    CPU work on Default, collect on main = A [OK]
Hint: Put heavy work in flowOn(Default), collect on main thread [OK]
Common Mistakes:
  • Using flowOn(Main) for heavy work
  • Confusing flowOn with collectOn
  • Running CPU work on IO dispatcher
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard