CoroutineModule

@Module
object CoroutineModule

Hilt module providing an application-scoped CoroutineScope.

Why This Module Exists

While you could create CoroutineScope(Dispatchers.Default) directly, injecting an application scope offers several advantages:

  1. Lifecycle-aware: Automatically tied to the application lifecycle

  2. Testable: Tests can inject a TestScope for deterministic execution

  3. Centralized: Single source of truth for app-wide coroutine operations

  4. Structured Concurrency: All app-level coroutines are children of this scope

SupervisorJob Decision

This scope uses SupervisorJob() instead of a regular Job. Here's why:

With Regular Job (NOT USED)

Parent Job fails

All children cancelled

Entire scope becomes unusable

With SupervisorJob (USED)

One child fails

Other children continue running

Scope remains usable

Example Scenario

@ApplicationScope scope
├─ DataSync coroutine (fails due to network error)
├─ AnalyticsLogger coroutine (keeps running ✓)
└─ CacheCleanup coroutine (keeps running ✓)

If we used a regular Job, the network error would cancel ALL operations. With SupervisorJob, only the failed coroutine is cancelled.

Architecture Decision

This template provides an ApplicationScope for operations that need to:

  • Survive configuration changes (screen rotations)

  • Run independently of any specific screen or ViewModel

  • Continue even when the user navigates away

However, most operations should use viewModelScope instead, as it's automatically cancelled when the ViewModel is cleared, preventing memory leaks.

See also

SupervisorJob
viewModelScope

Functions

Link copied to clipboard
@Provides
@Singleton
fun providesCoroutineScope(dispatcher: CoroutineDispatcher): CoroutineScope

Provides a singleton CoroutineScope tied to the application lifecycle.