I want to use a Worker in my Android app (pure Kotlin) to so some background work. I'm using Hilt for dependency injection, but I'm facing some problems when I need to pass a custom object to the Worker.
My code is as follows:
@HiltWorker
class BackgroundWorker @AssistedInject constructor(
@Assisted appContext: Context,
@Assisted workerParams: WorkerParameters,
val mockClass: MockClass
) : CoroutineWorker(appContext, workerParams) {
init {
Log.d("deb", "Worker: Initiated")
}
override suspend fun doWork(): Result {
Log.d("deb", "Worker: Doing work!")
return Result.success()
}
}
And my MockClass is:
@Module
@InstallIn(SingletonComponent::class)
object MockModule {
@Singleton
@Provides
fun provideMockClass(): MockClass = MockClass()
}
class MockClass{}
Inside my onCreate
function in my main activity I call:
WorkManager.getInstance(applicationContext).enqueue(
OneTimeWorkRequestBuilder<BackgroundWorker>().build()
)
to initiate the worker and call de doWork
function, but when I start the app, I don't see the logs
and the AppInspector
shows "Failed" as the WorkerStatus.
I know that my Application
class (annotated with @HiltAndroidApp
) is correctly configured (using WorkerFactory
, etc.) and the AndroidManifest.xml
is well configured (using the provider
tag, etc.), because when I comment out the line:
val mockClass: MockClass
then I see the logs
from inside my Worker
(both of them, the init
and the doWork
one). So it works perfectly fine! But when I uncomment the line (so that the mockClass
object is passed to the worker), the worker is not able to initiate.
Just for completion, here is my Manifest
:
<application
...
android:name=".MyApplication">
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
tools:node="remove">
</provider>
...
</>
, Application
class:
@HiltAndroidApp
class MyApplication : Application(), Configuration.Provider {
@Inject
lateinit var workerFactory: HiltWorkerFactory
override val workManagerConfiguration: Configuration
get() = Configuration.Builder()
.setWorkerFactory(workerFactory)
.build()
}
, the dependencies I'm using:
[verions]
hiltCommon = "1.2.0"
workerRuntimeKtx = "2.10.0"
hilt = "2.55"
hilt-work = "1.2.0"
kotlin = "2.1.0"
ksp = "2.1.0-1.0.29"
[libraries]
hilt-android = { group = "com.google.dagger", name = "hilt-android", version.ref = "hilt" }
hilt-compiler = { group = "com.google.dagger", name = "hilt-compiler", version.ref = "hilt" }
hilt-work = { group = "androidx.hilt", name = "hilt-work", version.ref = "hilt-work" }
androidx-hilt-common = { group = "androidx.hilt", name = "hilt-common", version.ref = "hiltCommon" }
androidx-worker-runtime-ktx = { group = "androidx.work", name = "work-runtime-ktx", version.ref = "workerRuntimeKtx" }
[plugins]
hilt = { id = "com.google.dagger.hilt.android", version.ref = "hilt" }
kotlin-ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
in module-level build.gradle
:
plugins{
...
alias(libs.plugins.hilt)
alias(libs.plugins.kotlin.ksp)
}
dependencies{
implementation(libs.androidx.worker.runtime.ktx)
implementation(libs.hilt.android)
implementation(libs.hilt.work)
implementation(libs.androidx.hilt.common)
ksp(libs.hilt.compiler){
exclude("META-INF/gradle/incremental.annotation.processors")
}
}
and in project-level build.gradle
:
plugins{
alias(libs.plugins.kotlin.ksp) apply false
alias(libs.plugins.hilt) apply false
}
I think my problem is somehow related to the DI and Hilt, but I cannot figure out what it is. I use Hilt
for dependency injection on other parts in my app, and they work okay.
Your Gradle setup for Hilt is off.
In your version catalog you need to replace the two libraries
hilt-compiler = { group = "com.google.dagger", name = "hilt-compiler", version.ref = "hilt" }
androidx-hilt-common = { group = "androidx.hilt", name = "hilt-common", version.ref = "hiltCommon" }
with these:
hilt-android-compiler = { group = "com.google.dagger", name = "hilt-android-compiler", version.ref = "hilt" }
androidx-hilt-compiler = { group = "androidx.hilt", name = "hilt-compiler", version.ref = "hilt-work" }
Now, in your gradle file replace
implementation(libs.androidx.hilt.common)
ksp(libs.hilt.compiler){
exclude("META-INF/gradle/incremental.annotation.processors")
}
accordingly with
ksp(libs.hilt.android.compiler)
ksp(libs.androidx.hilt.compiler)
The Hilt injection should now work without issues, even for the WorkManager.