Hilt 和 WorkManager 错误:lateinit 属性 WorkerFactory 尚未初始化

问题描述 投票:0回答:3

我正在尝试使用 Hilt 注入 WorkManager。 首先我实现文档:

使用类中的 @HiltWorker 注解和 Worker 对象的构造函数中的 @AssistedInject 注入 Worker。您只能在 Worker 对象中使用 @Singleton 或无范围绑定。您还必须使用 @Assisted 注释 Context 和 WorkerParameters 依赖项:

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

然后我从文档中应用了这个:

然后,让您的 Application 类实现 Configuration.Provider 接口,注入 HiltWorkFactory 的实例,并将其传递到 WorkManager 配置中,如下所示:

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

    @Inject lateinit var workerFactory: HiltWorkerFactory

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

}

最后,我处理文档中的这条注释:

注意:由于这会自定义 WorkManager 配置,因此您还必须按照 WorkManager 文档中的指定从 AndroidManifest.xml 文件中删除默认初始化程序。

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

但我收到此错误:

    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
...
android kotlin android-workmanager dagger-hilt
3个回答
6
投票

正如 @sanya5791 提到的,如果添加/更改启动提供程序不起作用,那么另一个要尝试的解决方案是添加 HiltWorkerFactoryEntryPoint,以防在 onCreate 之前调用workerConfiguration,并且可以按如下方式完成,以防链接不起作用完整解决方案如下:

  1. 更改 Android Manifest 文件以包含新的启动提供程序

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

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

  1. 如果第一个没有解决问题,那么不要直接注入workerFactory,而是使用辅助工厂进行注入,如下所示

@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()
}


1
投票

您初始化workmanager和workmanagerfactory的方式仅在workmanager版本2.5.X之前有效。随着 Workmanager 版本 2.6.x-alphaX 的更新,这种情况发生了变化,现在 Workmanager 正在使用 androidx.startup 来初始化 WorkManager。

这里有两个选择:我建议降级回 2.5.0,因为这是当前的稳定版本,或者更改初始化 Workmanager 的方式。

如果您想保留您的版本,请更改您的 Android 清单:

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

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

此外,请确保您具有以下依赖项:

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'

1
投票

解决了 2 个问题,这对我来说很有效:

  1. 删除默认初始化程序
  2. 按照此处的描述,通过 @EntryPoint 重构 HiltWorkerFactory 注入
© www.soinside.com 2019 - 2024. All rights reserved.