Injecting CoroutineWorker with Hilt : Could not instantiate woker
Asked Answered
S

3

20

Same questions have been asked but they didn't work for me , In the start I was using the latest version of work manager which is 2.7 alpha 3 but I downgraded since its only compatible to android 12 preview sdk , The error still remained there !
It cannot instantiate the worker because those dependencies are included in the constructor of the worker , It was working before I added them but there's no benefit of hilt if I can't add them so here's the situation :

Manifest does not contain any configuration related to work manager !

Application Class :

@HiltAndroidApp
class TimelineApp : Application() ,Configuration.Provider{

@Inject
lateinit var workerFactory: HiltWorkerFactory

override fun getWorkManagerConfiguration() =
    Configuration.Builder()
        .setWorkerFactory(workerFactory)
        .build()

}

Worker :

@HiltWorker
class DriveSyncWorker @AssistedInject constructor(
    @Assisted val context: Context,
    @Assisted workerParams: WorkerParameters,
    val dependency: StorageHelper,
)

Noticed : its not using HiltWorkFactory !

Error:

E/WM-WorkerFactory: Could not instantiate com.wakaztahir.timeline.utils.workers.DriveSyncWorker
    java.lang.NoSuchMethodException: com.wakaztahir.timeline.utils.workers.DriveSyncWorker.<init> [class android.content.Context, class androidx.work.WorkerParameters]
        at java.lang.Class.getConstructor0(Class.java:2332)
        at java.lang.Class.getDeclaredConstructor(Class.java:2170)
        at androidx.work.WorkerFactory.createWorkerWithDefaultFallback(WorkerFactory.java:95)
        at androidx.work.impl.WorkerWrapper.runWorker(WorkerWrapper.java:244)
        at androidx.work.impl.WorkerWrapper.run(WorkerWrapper.java:136)
        at androidx.work.impl.utils.SerialExecutor$Task.run(SerialExecutor.java:91)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:923)
E/WM-WorkerWrapper: Could not create Worker com.wakaztahir.timeline.utils.workers.DriveSyncWorker

Gradle :

implementation "com.google.dagger:hilt-android:$hilt_version"
kapt "com.google.dagger:hilt-compiler:$hilt_version"

def work_version = "2.6.0-alpha02"
implementation "androidx.work:work-runtime-ktx:$work_version"
implementation 'androidx.hilt:hilt-work:1.0.0-beta01'
implementation 'com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava'

Linked :

Cannot Inject coroutine worker using hilt
Injecting coroutine worker using hilt

Spancake answered 4/5, 2021 at 15:51 Comment(1)
In my case I was using ksp instead of kapt. This caused the issue because the hilt-compiler below 1.1.0 did not support it. here is link to release notes. developer.android.com/jetpack/androidx/releases/…Analects
V
32

Since you are using work manager version above than 2.6.0-alpha01 , Work Manager version above 2.6.0-alpha01 uses startup initializer Read Here

Add this provider to you app AndroidManifest.xml:

<application ... >

 <provider
    android:name="androidx.startup.InitializationProvider"
    android:authorities="${applicationId}.androidx-startup"
    tools:node="remove">
 </provider>

</application>
Vocal answered 10/5, 2021 at 10:58 Comment(4)
But you are overriding getWorkManagerConfiguration from the application (since Hilt needs it), thus you need to add that provider to the manifest.Vocal
I did it , It still gives the error ! It says in the docs : Note: Because this customizes the WorkManager configuration, you also must remove the default initializer from the AndroidManifest.xml file as specified in the WorkManager docs. developer.android.com/training/dependency-injection/…Spancake
Thanks for trying to help though !Spancake
It fix my issues using it with workmanager version 2.7.0-rc01Backwater
J
33

You are missing an extra kapt definition in your gradle file:

// When using Kotlin.
kapt("androidx.hilt:hilt-compiler:1.0.0")

// When using Java.
annotationProcessor("androidx.hilt:hilt-compiler:1.0.0")

see documentation

Jebel answered 27/8, 2021 at 19:32 Comment(3)
I am using kapt "com.google.dagger:hilt-compiler:$hilt_version" but no need to worry , The problem was solved with the answer above , check the editsSpancake
I was writing this answer, as I have faced the same issue yesterday, and having the kapt "com.google.dagger:hilt-compiler:$hilt_version" only was not enough. After adding the extra kapt("androidx.hilt:hilt-compiler:1.0.0") everything was fine. So my working solution is to have both kapt definitons + the accepted manifest settingJebel
Good answer. It's worth mentioning that in a multi module project this should be added to the module build.gradle which contains the Worker implementationsMozzetta
V
32

Since you are using work manager version above than 2.6.0-alpha01 , Work Manager version above 2.6.0-alpha01 uses startup initializer Read Here

Add this provider to you app AndroidManifest.xml:

<application ... >

 <provider
    android:name="androidx.startup.InitializationProvider"
    android:authorities="${applicationId}.androidx-startup"
    tools:node="remove">
 </provider>

</application>
Vocal answered 10/5, 2021 at 10:58 Comment(4)
But you are overriding getWorkManagerConfiguration from the application (since Hilt needs it), thus you need to add that provider to the manifest.Vocal
I did it , It still gives the error ! It says in the docs : Note: Because this customizes the WorkManager configuration, you also must remove the default initializer from the AndroidManifest.xml file as specified in the WorkManager docs. developer.android.com/training/dependency-injection/…Spancake
Thanks for trying to help though !Spancake
It fix my issues using it with workmanager version 2.7.0-rc01Backwater
S
4

I am using WorkManager 2.7.1 with hilt. According to doc, since WorkManager 2.6, you should remove [androidx.work.WorkManagerInitializer] from start-up provider instead of [androidx.work.impl.WorkManagerInitializer].

    <provider
        android:name="androidx.startup.InitializationProvider"
        android:authorities="${applicationId}.androidx-startup"
        android:exported="false"
        tools:node="merge">
        <!-- If you are using androidx.startup to initialize other components -->
        <meta-data
            android:name="androidx.work.WorkManagerInitializer"
            android:value="androidx.startup"
            tools:node="remove" />
    </provider>
Stratus answered 6/4, 2022 at 6:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.