简体   繁体   English

匕首柄注入活动导致 UninitializedPropertyAccessException 错误

[英]Dagger hilt injecting into activity results in UninitializedPropertyAccessException error

I am trying to inject a class into an activity using dagger hilt using a Module.我正在尝试使用模块将 class 注入到使用匕首柄的活动中。 I've looked through tutorials and countless SO posts.我浏览了教程和无数 SO 帖子。 I cannot tell what I'm doing wrong.我不知道我做错了什么。

I have a DataStoreManger class that i'm trying to use in an activity.我有一个要在活动中使用的 DataStoreManger class。

class DataStoreManager (@ApplicationContext appContext: Context) {...}

I have an AppModule that provides a DataStoreManager.我有一个提供 DataStoreManager 的 AppModule。

@Module
@InstallIn(SingletonComponent::class)
object AppModule {
   @Provides
   @Singleton
   fun provideDataStoreManager(@ApplicationContext appContext: Context): 
      DataStoreManager = DataStoreManager(appContext)
}

Then I'm trying to use DataStoreManager in MainActivity.然后我尝试在 MainActivity 中使用 DataStoreManager。

@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
   @Inject lateinit var dataStoreManager: DataStoreManager

   private val userPreferencesFlow = dataStoreManager.userPreferencesFlow
}

This results in an uninitialized property access exception这导致未初始化的属性访问异常

     Caused by: kotlin.UninitializedPropertyAccessException: lateinit property 
     dataStoreManager has not been initialized

When you use当你使用

@Inject lateinit var dataStoreManager

The dataStoreManager is only actually injected during the call to super.onCreate() . dataStoreManager仅在调用super.onCreate()期间实际注入。

However, when you create a property such as但是,当您创建诸如

private val userPreferencesFlow = dataStoreManager.userPreferencesFlow

This property is created immediately as part of the construction of your MainActivity class - it doesn't wait until onCreate() runs, hence the error you are receiving.此属性是作为MainActivity class 构造的一部分立即创建的 - 它不会等到onCreate()运行,因此您会收到错误。

Generally, the easiest way to avoid this is by only access the userPreferencesFlow from your injected manager when you actually want to collect it, which is presumably after super.onCreate() .通常,避免这种情况的最简单方法是仅在您真正想要收集时从注入的管理器访问userPreferencesFlow ,这大概是在super.onCreate()之后。

However, if you want to still create your flow as a member variable at the activity level, you can use by lazy :但是,如果您仍想在活动级别将流创建为成员变量,则可以使用by lazy

private val userPreferencesFlow by lazy {
    dataStoreManager.userPreferencesFlow
}

The lazy block will only be executed lazily - eg, the first time you actually use the member variable, thus ensuring that your @Inject variable has actually been injected. lazy块只会被惰性地执行——例如,当你第一次真正使用成员变量时,从而确保你的@Inject变量确实被注入了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM