CoroutineScope vs CoroutineContext

Coroutines Mid-level Kotlin 2.0+ API 24+ Reviewed By Best Latest Apps

Predict the output

What does this print?

fun main() = runBlocking {
    val ctx = Dispatchers.Default + CoroutineName("first") + CoroutineName("second")
    launch(ctx) {
        println(coroutineContext[CoroutineName]?.name)
    }.join()
}
Options
Hint 1 of 2

How many CoroutineName elements can a context hold?

Hint 2 of 2

Which side wins in a + b?

Choose an answer, then open Show answer below to check it.

Show answer

Answer: A second

Correct. Context elements are keyed; the right-hand CoroutineName replaces the left one.

Why not the others?
  • B first. The left element is replaced by the later one with the same key.
  • C first second. A context holds at most one element per key.
  • D null. launch keeps the name from the context you passed in.

30-second answer

A CoroutineContext is a set of elements that configure a coroutine: its Job, dispatcher, name and exception handler. A CoroutineScope is just an object that holds a context so you can launch children into it. The scope defines lifetime through its Job; the context is the configuration every child inherits.

Practise saying it · 35 s. No recording, just a timer

Explain scope vs context.

Say your answer out loud, then check which of these points you covered:

  • Context is keyed configuration
  • Scope holds a context and defines lifetime
  • Children inherit and override
  • viewModelScope is SupervisorJob + Main.immediate

Deep dive

Context elements are keyed, so Dispatchers.IO + CoroutineName("sync") combines them and the right-hand side wins on conflicts.

A child's context is the parent's context plus whatever you pass to launch, with a new child Job.

viewModelScope is SupervisorJob() + Dispatchers.Main.immediate, cancelled when the ViewModel is cleared, just before onCleared().

coroutineContext inside a suspend function gives you the current context, for example to check isActive.

Common mistakes

  • Treating scope and context as the same thing.
  • Creating a CoroutineScope(Dispatchers.IO) in a class and never cancelling it.
  • Passing a Job in the context of launch and breaking the parent link.

Senior take & follow-ups

The useful line: scope is about lifetime, context is about configuration. Then show how a child inherits and overrides.

Follow-up questions

Think of your answer first, then open the hint.

  1. What is in viewModelScope's context?

    Show hint

    A SupervisorJob and Dispatchers.Main.immediate.

  2. How do you make an application-wide scope safely?

    Show hint

    Create it once with a SupervisorJob, inject it, and never use GlobalScope.

Suggest a fix if something here is wrong or out of date.