I encountered an exception while trying to enqueue a work using Hilt and WorkManager:
Could not instantiate my.example.package.widget.ExampleWorker
java.lang.NoSuchMethodException: my.example.package.widget.ExampleWorker.<init> [class android.content.Context, class androidx.work.WorkerParameters]
at java.lang.Class.getConstructor0(Class.java:3325)
at java.lang.Class.getDeclaredConstructor(Class.java:3063)
at androidx.work.WorkerFactory.createWorkerWithDefaultFallback(WorkerFactory.java:95)
at androidx.work.impl.WorkerWrapper.runWorker(WorkerWrapper.java:243)
at androidx.work.impl.WorkerWrapper.run(WorkerWrapper.java:145)
at androidx.work.impl.utils.SerialExecutorImpl$Task.run(SerialExecutorImpl.java:96)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
at java.lang.Thread.run(Thread.java:1012)
14:26:51.737 E Could not create Worker my.example.package.widget.ExampleWorker
Here's my Worker class:
@HiltWorker
class ExampleWorker @AssistedInject constructor(
@Assisted private val context: Context,
@Assisted workerParameters: WorkerParameters,
private val exampleUseCase: ExampleUseCase
) : CoroutineWorker(context, workerParameters) {
companion object {
private val uniqueWorkName = ExampleWorker::class.java.simpleName
fun enqueue(context: Context) {
val manager = WorkManager.getInstance(context)
val requestBuilder = PeriodicWorkRequestBuilder<ExampleWorker>(
Duration.ofMinutes(15)
)
manager.enqueueUniquePeriodicWork(
uniqueWorkName,
ExistingPeriodicWorkPolicy.UPDATE,
requestBuilder.build()
)
}
}
override suspend fun doWork(): Result {
exampleUseCase.invoke()
return Result.success()
}
}
My HiltApp:
@HiltAndroidApp
class HiltApp : Application(), Configuration.Provider {
// https://developer.android.com/training/dependency-injection/hilt-jetpack#workmanager
@Inject
lateinit var workerFactory: HiltWorkerFactory
override fun getWorkManagerConfiguration(): Configuration =
Configuration.Builder()
.setWorkerFactory(workerFactory)
.build()
}
In the AndroidManifest.xml file, I removed the default initializer as per the tutorial: https://developer.android.com/guide/background/persistent/configuration/custom-configuration#remove-default
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
tools:node="remove" />
The simplified class I'm injecting in my worker:
class ExampleUseCase @Inject constructor() {
operator fun invoke() {}
}
Here are my dependencies:
implementation("com.google.dagger:hilt-android:2.48.1")
ksp("com.google.dagger:hilt-android-compiler:2.48.1")
implementation("androidx.hilt:hilt-work:1.0.0")
ksp("androidx.hilt:hilt-compiler:1.0.0")
implementation("androidx.work:work-runtime-ktx:2.8.1")
implementation("androidx.work:work-runtime:2.8.1")
Gradle plugin version: 8.1.1, Kotlin version: 1.9.10
I encountered this exception after updating several dependencies in my project, such as the Gradle Plugin from 7.4.1 to 8.1.1, Kotlin from 1.8.0 to 1.9.10, Hilt from 2.44.2 to 2.48.1, and the compile SDK from 33 to 34, among others.
I attempted to downgrade Hilt, however, in doing so, I encountered new exceptions, which I believe may be caused by version incompatibilities among all these upgraded libraries.
If I remove the exampleUseCase
parameter from the worker constructor, the NoSuchMethodException
is resolved. However, I require this field in the doWork()
method. I attempted to inject it as lateinit var
, but it isn't initialized by the time it is called.
I've checked a lot of documentation, but I'm still missing something. I would greatly appreciate any help!
I think that's a bug in KSP, see this