Understanding Coroutine Cancellation in Kotlin — Complete Guide with Real Android Examples
When Android developers start using Kotlin Coroutines, most learn:
Understanding Coroutine Cancellation in Kotlin — Complete Guide with Real Android Examples

When Android developers start using Kotlin Coroutines, most learn:
viewModelScope.launch { }
But very few truly understand how coroutine cancellation works internally.
And cancellation is one of the most important concepts in real-world Android apps.
Without proper cancellation handling:
- Multiple API calls run unnecessarily
- Memory leaks happen
- Old search results overwrite new ones
- Background tasks continue after screen destruction
- App performance suffers
In this article, we’ll deeply understand:
- Job cancellation
- Scope cancellation
- Parent-child cancellation
coroutineScopesupervisorScope- Cooperative cancellation
CancellationException- Timeout cancellation
- Real production use cases
What is Coroutine Cancellation?
Coroutine cancellation means:
Stopping a coroutine before it completes.
Coroutines are designed to be lightweight and lifecycle-aware.
Unlike Threads, coroutines support structured concurrency and automatic cancellation propagation.
1. Job Cancellation
The simplest type of cancellation.
private var loadJob: Job? = null
fun loadData(){
loadJob?.cancel()
loadJob = viewModelScope.launch{
delay(500)
println ("API Completed")
}
}
What happens here?
When loadData() is called again:
- Previous coroutine gets cancelled
- New coroutine starts
Real Android Use Case
Perfect for:
- Search APIs
- Retry button
- Pagination
- Debounce
- Latest-request-only architecture
Example: Search API
private var searchJob: Job? = null
fun search(query: String) {
searchJob?.cancel()
searchJob = viewModelScope.launch {
delay(500)
repository.search(query)
}
}
Why?
If user types:
a
an
and
andr
andro
android
Without cancellation:
- 6 API calls happen
With cancellation:
- Only latest request executes
This is a real production pattern.
2. Scope Cancellation
When a scope cancels:
- All child coroutines cancel automatically.
Example:
viewModelScope.launch {
launch {
delay(5000)
println("Task 1")
}
launch {
delay(5000)
println("Task 2")
}
}
If:
viewModelScope.cancel()
Both child coroutines cancel.
Why This Matters
This is called:
Structured Concurrency
Kotlin ensures:
- parent controls children
- no orphan coroutines
- safer concurrency
3. Parent-Child Cancellation
By default:
If one child fails, all siblings cancel.
Example:
coroutineScope {
launch {
throw Exception("API Failed")
}
launch {
delay(5000)
println("Second API")
}
}
Result:
- Second coroutine also cancels
Why?
Because coroutineScope follows structured concurrency strictly.
This prevents inconsistent state.
4. supervisorScope
One of the most important coroutine concepts.
Example:
supervisorScope {
launch {
throw Exception("API Failed")
}
launch {
delay(5000)
println("Second API Still Running")
}
}
Now:
- First coroutine fails
- Second coroutine survives
Real Android Example
Imagine:
- Coin API fails
- Pokemon API succeeds
You still want partial UI data.
Example:
supervisorScope {
val coinDeferred = async {
runCatching {
useCase.getCoinList()
}
}
val pokemonDeferred = async {
runCatching {
useCase.getPokemonList()
}
}
val coinResult = coinDeferred.await()
val pokemonResult = pokemonDeferred.await()
}
This is a very common MVI production pattern.
coroutineScope vs supervisorScope
FeaturecoroutineScopesupervisorScopeOne child failsAll cancelOthers surviveStructured concurrencyStrictRelaxedBest forDependent tasksIndependent tasks
5. Cooperative Cancellation
Very important concept.
Coroutines do NOT stop immediately.
They stop only at:
delay()await()yield()- suspension points
Example:
while(true) {}
This NEVER cancels.
Correct Way
while(isActive) {}
Or:
ensureActive()
Why?
Coroutine cancellation is cooperative.
The coroutine must check whether it is cancelled.
6. CancellationException
Internally, cancellation works using:
CancellationException
And this is VERY important.
Wrong Way
catch (e: Exception) {}
This accidentally catches cancellation too.
Result:
- coroutine may not cancel properly
Correct Way
catch (e: CancellationException) {
throw e
}
catch (e: Exception) {}
Why Re-throw?
Because cancellation is NOT a failure.
It is a control signal.
7. async Cancellation
You can cancel individual async tasks.
val deferred = async {
delay(5000)
"Result"
}
deferred.cancel()
Only this async block cancels.
8. Timeout Cancellation
Very useful for APIs.
withTimeout(3000) {
repository.getData()
}
If API takes more than 3 seconds:
- coroutine automatically cancels
Safe Timeout Example
val result = withTimeoutOrNull(3000) {
repository.getData()
}
Returns:
nullinstead of crash
9. Lifecycle-Aware Cancellation
Android already provides automatic cancellation.
viewModelScope
Cancels when:
- ViewModel clears
lifecycleScope
Cancels when:
- Lifecycle destroyed
Example:
viewModelScope.launch {}
No need to manually cancel on screen destroy.
Kotlin handles it automatically.
Production-Level Example
@HiltViewModel
class HomeViewModel @Inject constructor(
private val repository: Repository
) : ViewModel() {
private var loadJob: Job? = null
fun loadData() {
loadJob?.cancel()
loadJob = viewModelScope.launch {
supervisorScope {
val api1 = async {
repository.getCoins()
}
val api2 = async {
repository.getPokemon()
}
val coins = api1.await()
val pokemon = api2.await()
}
}
}
}
When Should You Use Cancellation?
ScenarioUse Cancellation?Search APIYesRetry buttonYesPaginationYesFile UploadYesParallel APIsUsuallyOne-time splash APINot necessary
Final Thoughts
Coroutine cancellation is not just:
job.cancel()
It is deeply connected with:
- structured concurrency
- lifecycle awareness
- failure propagation
- app performance
- memory management
Understanding cancellation properly will make your Android architecture significantly more production-ready.
Especially in:
- MVI
- Clean Architecture
- Compose apps
- Parallel APIs
- Real-time search systems
Mastering cancellation is one of the biggest steps toward becoming an advanced Kotlin developer.
메타데이터
- post_id
- 391a52ad8d8d
- slug
- understanding-coroutine-cancellation-in-kotlin-complete-guide-with-real-android-examples-391a52ad8d8d
- url
- https://medium.com/@meaghosh/understanding-coroutine-cancellation-in-kotlin-complete-guide-with-real-android-examples-391a52ad8d8d
- canonical_url
- https://medium.com/@meaghosh/understanding-coroutine-cancellation-in-kotlin-complete-guide-with-real-android-examples-391a52ad8d8d
- author_url
- https://medium.com/@meaghosh
- status
- ok
- fetched_at
- 2026-06-23 03:48:11