Jobs help manage background tasks in Kotlin. Understanding their lifecycle and how to stop them safely keeps your app responsive and efficient.
Job lifecycle and cancellation in Kotlin
val job = CoroutineScope(Dispatchers.Default).launch { // your background task here } // To cancel the job: job.cancel() // To check if job is active: if (job.isActive) { // do something }
launch starts a new job (background task).
cancel() stops the job safely.
val job = CoroutineScope(Dispatchers.Default).launch { println("Job started") delay(1000) println("Job finished") } job.cancel()
val job = CoroutineScope(Dispatchers.Default).launch { repeat(5) { i -> println("Working on step $i") delay(500) } } // Cancel after 1 second CoroutineScope(Dispatchers.Default).launch { delay(1000) job.cancel() println("Job cancelled") }
This program starts a job that prints steps every 0.5 seconds. After about 1.2 seconds, it cancels the job. The job catches the cancellation, prints a message, and does cleanup. Finally, the main program confirms the job is done.
import kotlinx.coroutines.* fun main() = runBlocking { val job = launch { try { repeat(5) { i -> println("Working on step $i") delay(500) } } catch (e: CancellationException) { println("Job was cancelled") } finally { println("Cleanup after job") } } delay(1200) // Let the job run a bit println("Requesting cancellation") job.cancelAndJoin() // Cancel and wait for job to finish println("Job is completed: ${job.isCompleted}") }
Always handle CancellationException inside jobs to clean up resources.
Calling cancel() requests cancellation but does not wait; use cancelAndJoin() to wait until the job finishes.
A job is isActive while running and isCompleted after finishing or cancellation.
Jobs represent background tasks with a clear lifecycle: active, cancelled, completed.
You can stop jobs safely using cancel() or cancelAndJoin().
Handling cancellation lets you clean up and keep your app responsive.
Practice
Job?Solution
Step 1: Understand Job lifecycle states
A Kotlin Job begins in an active state, meaning it is running or ready to run.Step 2: Recognize cancellation and completion
A Job can be cancelled to stop its work, and after finishing or cancellation, it reaches a completed state.Final Answer:
A job starts active, can be cancelled, and then completes. -> Option CQuick Check:
Job lifecycle = active -> cancelled -> completed [OK]
- Thinking jobs start cancelled
- Assuming jobs never complete
- Confusing job states order
Solution
Step 1: Identify cancellation with waiting
The methodcancelAndJoin()cancels the job and suspends until it finishes.Step 2: Differentiate from other methods
cancel()only requests cancellation without waiting;join()waits but doesn't cancel;start()begins a job.Final Answer:
job.cancelAndJoin() -> Option AQuick Check:
Cancel and wait = cancelAndJoin() [OK]
- Using cancel() without waiting
- Confusing join() with cancel
- Calling start() to cancel
val job = CoroutineScope(Dispatchers.Default).launch {
repeat(3) { i ->
println("Working on $i...")
delay(100)
}
}
job.cancel()
Thread.sleep(500)Solution
Step 1: Analyze job launch and cancellation
The job starts and prints "Working on 0...", then delays. The cancel() is called immediately after launch.Step 2: Understand cancellation effect
Because cancellation happens quickly, some iterations may run before the job stops, so partial output appears.Final Answer:
Prints some "Working on" lines before stopping -> Option BQuick Check:
Partial output due to quick cancel [OK]
- Expecting all lines printed
- Expecting no output at all
- Assuming exception is printed
val job = CoroutineScope(Dispatchers.Default).launch {
try {
repeat(5) {
println("Working...")
delay(100)
}
} catch (e: Exception) {
println("Cancelled")
}
}
job.cancelAndJoin()Solution
Step 1: Understand cancellation exception type
Cancellation throwsCancellationException, which is a subclass ofThrowablebut notException.Step 2: Recognize catch block limitation
SinceCancellationExceptionis not caught bycatch (e: Exception), the cancellation is not handled as intended.Final Answer:
Catching Exception does not handle cancellation properly -> Option DQuick Check:
Catch CancellationException, not Exception [OK]
- Catching Exception instead of CancellationException
- Calling cancelAndJoin() incorrectly
- Thinking delay() is invalid inside launch
Solution
Step 1: Understand safe cancellation
UsingcancelAndJoin()cancels the job and waits until it fully stops, ensuring no work is left running.Step 2: Perform cleanup after cancellation
AftercancelAndJoin()returns, it's safe to run cleanup code because the job is fully cancelled.Final Answer:
Use job.cancelAndJoin() then run cleanup code after it returns. -> Option AQuick Check:
Cancel and wait before cleanup = cancelAndJoin() [OK]
- Starting cleanup before job stops
- Ignoring cancellation
- Using join() without cancelling
Ready to prove it?
Pass the test and this pattern moves unknown
