CoroutineWorker

CoroutineWorker and Hilt Integration

A plain Worker blocks a background thread in doWork(). A CoroutineWorker makes doWork() a suspend function on Dispatchers.Default, so it can call BookNest's repository directly, and stopping the work cancels the coroutine. Since WorkManager 2.9 234 it lives in work-runtime; work-runtime-ktx is empty.

WorkManager builds workers from a Context and WorkerParameters alone. androidx.hilt:hilt-work (1.4.0, with ksp on androidx.hilt:hilt-compiler) generates a factory per @HiltWorker; those two arguments are @Assisted, the rest come from Hilt:

sync/CatalogSyncWorker.kt: a Hilt-injected CoroutineWorkerKotlin
@HiltWorker
class CatalogSyncWorker @AssistedInject constructor(
  @Assisted context: Context,                       // supplied by WorkManager
  @Assisted params: WorkerParameters,
  private val repo: BookRepository,                 // supplied by Hilt
) : CoroutineWorker(context, params) {
  override suspend fun doWork(): Result {
    ...
    val before = cachedBooks()                      // prices before the refresh
    return when {
      repo.refresh() -> Result.success(workDataOf(KEY_BOOKS to afterSync(before)))
      runAttemptCount < 4 -> Result.retry()        // back off, then run again
      else -> Result.failure()
    }
  }
  ...
}

afterSync() returns the book count (Notifications and Widgets adds notifications and a widget). success() may carry output Data, retry() applies the backoff, and failure() stops, failing the rest of a chain.

BookNestApp then implements Configuration.Provider: its workManagerConfiguration property (the Hilt guide still shows the old getWorkManagerConfiguration()) passes an injected HiltWorkerFactory to Configuration.Builder().setWorkerFactory(). The manifest removes WorkManager's default initializer (tools:node="remove" on the WorkManagerInitializer meta-data), which would start WorkManager with the default factory. SyncReportWorker has no @HiltWorker, so WorkManager builds it by reflection.