Skip to main content
Version: 4.2

WorkManager

Koin integrates with Android WorkManager to enable constructor injection in Workers.

Setup

Add Dependencies

implementation "io.insert-koin:koin-android:$koin_version"
implementation "io.insert-koin:koin-androidx-workmanager:$koin_version"

Configure WorkManager

Set up the Koin WorkManager factory in your Application:

class MainApplication : Application() {

override fun onCreate() {
super.onCreate()

startKoin {
androidContext(this@MainApplication)
workManagerFactory()
modules(appModule)
}
}
}

Disable Default Initializer

Add to your AndroidManifest.xml to disable the default WorkManager initializer:

<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false"
tools:node="merge">
<meta-data
android:name="androidx.work.WorkManagerInitializer"
android:value="androidx.startup"
tools:node="remove" />
</provider>

Declaring Workers

Compiler Plugin DSL

class MyWorker(
context: Context,
workerParams: WorkerParameters,
private val myService: MyService
) : CoroutineWorker(context, workerParams) {

override suspend fun doWork(): Result {
myService.performTask()
return Result.success()
}
}

val appModule = module {
single<MyService>()
worker<MyWorker>()
}

Annotations

@KoinWorker
class MyWorker(
context: Context,
workerParams: WorkerParameters,
private val myService: MyService
) : CoroutineWorker(context, workerParams) {

override suspend fun doWork(): Result {
myService.performTask()
return Result.success()
}
}

@Singleton
class MyService

Classic DSL

val appModule = module {
single { MyService() }
worker { params ->
MyWorker(
context = params.get(),
workerParams = params.get(),
myService = get()
)
}
}

Enqueuing Work

Use WorkManager normally to enqueue your worker:

val workRequest = OneTimeWorkRequestBuilder<MyWorker>().build()
WorkManager.getInstance(context).enqueue(workRequest)

Worker with Parameters

Pass parameters via WorkManager's input data:

@KoinWorker
class SyncWorker(
context: Context,
workerParams: WorkerParameters,
private val repository: DataRepository
) : CoroutineWorker(context, workerParams) {

override suspend fun doWork(): Result {
val userId = inputData.getString("USER_ID") ?: return Result.failure()
repository.syncUser(userId)
return Result.success()
}
}

Enqueue with data:

val workRequest = OneTimeWorkRequestBuilder<SyncWorker>()
.setInputData(workDataOf("USER_ID" to "123"))
.build()

WorkManager.getInstance(context).enqueue(workRequest)

Quick Reference

ApproachDeclaration
Compiler Plugin DSLworker<MyWorker>()
Annotations@KoinWorker
Classic DSLworker { params -> MyWorker(params.get(), params.get(), get()) }
SetupCode
Enable factoryworkManagerFactory() in startKoin
Disable defaultRemove WorkManagerInitializer in manifest

Next Steps