Hilt and WorkManager error : lateinit property WorkerFactory has not been initialized
Asked Answered
M

3

6

I'm trying to inject WorkManager with Hilt. first I implement the documentation:

Inject a Worker using the @HiltWorker annotation in the class and @AssistedInject in the Worker object's constructor. You can use only @Singleton or unscoped bindings in Worker objects. You must also annotate the Context and WorkerParameters dependencies with @Assisted:

 @HiltWorker
 class RetreiveQuestionWorkManager @AssistedInject constructor(
    @Assisted val appContext : Context,
    @Assisted val workerParameters: WorkerParameters,
    val questionDao: QuestionDao,
    val questionCacheMapper: QuestionCacheMapper)
    : CoroutineWorker(appContext, workerParameters)  {
    ... 
    }

then I applied this from documentation:

Then, have your Application class implement the Configuration.Provider interface, inject an instance of HiltWorkFactory, and pass it into the WorkManager configuration as follows:

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

    @Inject lateinit var workerFactory: HiltWorkerFactory

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

}

finally, I take care of this note from the documentation:

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.

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

but i get this error:

    java.lang.RuntimeException: Unable to start activity ComponentInfo{mohalim.contest.alarm/mohalim.contest.alarm.ui.splash.SplashActivity}: kotlin.UninitializedPropertyAccessException: lateinit property workerFactory has not been initialized
...
     Caused by: kotlin.UninitializedPropertyAccessException: lateinit property workerFactory has not been initialized
...
Mortise answered 5/8, 2021 at 19:45 Comment(2)
Which workmanager version are you using? Did you add your app class to your manifest? Did you add all necessary dependencies?Button
I'm using work manager version 2.7.0-alpha05, I added my app class to the manifest, and here is my hilt dependencies I use implementation("com.google.dagger:hilt-android:$hilt_version") kapt("com.google.dagger:hilt-android-compiler:$hilt_version") implementation("androidx.hilt:hilt-work:1.0.0") kapt("androidx.hilt:hilt-compiler:1.0.0")Mortise
B
1

The way you initialized your workmanager and workmanagerfactory is only working till workmanager version 2.5.X. With the update of Workmanager Version 2.6.x-alphaX this changed and now workmanager is using androidx.startup to initialize WorkManager.

You have two options here: Either downgrade back to 2.5.0 which I would suggest, because this is the current stable version OR change the way you initialize your workmanager.

If you want to keep your version, then change your Android Manifest the following:

<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.impl.WorkManagerInitializer"
        android:value="androidx.startup"
        tools:node="remove" />
 </provider>

OR

 <!-- If you want to disable android.startup completely. -->
 <provider
    android:name="androidx.startup.InitializationProvider"
    android:authorities="${applicationId}.androidx-startup"
    tools:node="remove">
 </provider>

Furthermore, make sure you have the following dependencies:

implementation "com.google.dagger:hilt-android:$dagger_hilt_version"
kapt "com.google.dagger:hilt-compiler:$dagger_hilt_version"
kapt 'androidx.hilt:hilt-compiler:1.0.0'
implementation "androidx.hilt:hilt-work:1.0.0"

implementation 'androidx.work:work-runtime-ktx:2.7.0-alpha05'
Button answered 6/8, 2021 at 14:15 Comment(3)
I tried to downgrade to 2.5.0 version and remove the default initialization of work manager in manifest by androidx.work.impl.WorkManagerInitializer instead of androidx.startup.InitializationProvider with version 2.5.0 then I'm already using androidx.startup.InitializationProvider with the current version 2.7.0-alpha05. the same problem still exists, thank you.Mortise
Maybe start a new project, test if the way you initialize workmanager etc. works and then try to do the same in your existing project.Button
finally, After starting a new project and move all the code of the old project to the new one, it works like a charm. I don't know what is the problem, but I think it happened because of updating the android studio to the arctic fox version. Thank you.Mortise
J
6

As @sanya5791 mentioned if adding/changing the startup provider didn't work then the other solution to try is to add a HiltWorkerFactoryEntryPoint in case the workerConfiguration gets called before onCreate and it can be done as follows in case the links don't work the full solution as below:

  1. Change Android Manifest file to include the new startup provider

<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>

or

<!-- If you want to disable android.startup completely. -->
 <provider
    android:name="androidx.startup.InitializationProvider"
    android:authorities="${applicationId}.androidx-startup"
    tools:node="remove">
  1. If the first didn't resolve the issue then instead of injecting the workerFactory directly inject using assisted factory as below

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

    @EntryPoint
    @InstallIn(SingletonComponent::class)
    interface HiltWorkerFactoryEntryPoint {
        fun workerFactory(): HiltWorkerFactory
    }

    override fun getWorkManagerConfiguration() =
        Configuration.Builder()
            .setWorkerFactory(EntryPoints.get(this, HiltWorkerFactoryEntryPoint::class.java).workerFactory())
            .build()
}
Jeremiad answered 13/10, 2022 at 15:30 Comment(0)
B
1

The way you initialized your workmanager and workmanagerfactory is only working till workmanager version 2.5.X. With the update of Workmanager Version 2.6.x-alphaX this changed and now workmanager is using androidx.startup to initialize WorkManager.

You have two options here: Either downgrade back to 2.5.0 which I would suggest, because this is the current stable version OR change the way you initialize your workmanager.

If you want to keep your version, then change your Android Manifest the following:

<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.impl.WorkManagerInitializer"
        android:value="androidx.startup"
        tools:node="remove" />
 </provider>

OR

 <!-- If you want to disable android.startup completely. -->
 <provider
    android:name="androidx.startup.InitializationProvider"
    android:authorities="${applicationId}.androidx-startup"
    tools:node="remove">
 </provider>

Furthermore, make sure you have the following dependencies:

implementation "com.google.dagger:hilt-android:$dagger_hilt_version"
kapt "com.google.dagger:hilt-compiler:$dagger_hilt_version"
kapt 'androidx.hilt:hilt-compiler:1.0.0'
implementation "androidx.hilt:hilt-work:1.0.0"

implementation 'androidx.work:work-runtime-ktx:2.7.0-alpha05'
Button answered 6/8, 2021 at 14:15 Comment(3)
I tried to downgrade to 2.5.0 version and remove the default initialization of work manager in manifest by androidx.work.impl.WorkManagerInitializer instead of androidx.startup.InitializationProvider with version 2.5.0 then I'm already using androidx.startup.InitializationProvider with the current version 2.7.0-alpha05. the same problem still exists, thank you.Mortise
Maybe start a new project, test if the way you initialize workmanager etc. works and then try to do the same in your existing project.Button
finally, After starting a new project and move all the code of the old project to the new one, it works like a charm. I don't know what is the problem, but I think it happened because of updating the android studio to the arctic fox version. Thank you.Mortise
M
1

resolving 2 issues made it work for me:

  1. Remove the default initializer
  2. Refactor HiltWorkerFactory injection through @EntryPoint as described here
Myriam answered 17/11, 2021 at 18:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.