ViewModel中的Android Hilt Dagger 注入(inject)接口(interface)@ViewModelInject得到了UninitializedPropertyAccessException

标签 android dependency-injection android-viewmodel dagger-hilt

我正在尝试 Hilt 代码实验室
https://codelabs.developers.google.com/codelabs/android-hilt#10
它与 Activity 和 Fragment 配合得很好
记录器是一个 RoomDB
然后我尝试用这个 article 将记录器注入(inject)到 viewModel 中。
通过添加

implementation "androidx.hilt:hilt-lifecycle-viewmodel
    :1.0.0-alpha02"
kapt 'androidx.hilt:hilt-compiler:1.0.0-alpha02'
查看模型代码
class RecordFragmentViewModel @ViewModelInject constructor(@Assisted private val savedStateHandle: SavedStateHandle) :
    ViewModel() {
    @DatabaseLogger
    @Inject
    lateinit var logger: LoggerDataSource
类记录器注入(inject)
 class LoggerLocalDataSource 
@Inject constructor(private val logDao: LogDao) : LoggerDataSource {
记录模块
@Qualifier
annotation class InMemoryLogger

@Qualifier
annotation class DatabaseLogger

@InstallIn(ApplicationComponent::class)
@Module
abstract class LoggingDatabaseModule {

    @DatabaseLogger
    @Singleton
    @Binds
    abstract fun bindDatabaseLogger(impl: LoggerLocalDataSource): LoggerDataSource
}

@InstallIn(ActivityComponent::class)
@Module
abstract class LoggingInMemoryModule {

    @InMemoryLogger
    @ActivityScoped
    @Binds
    abstract fun bindInMemoryLogger(impl: LoggerInMemoryDataSource): LoggerDataSource
}
数据库模块
@InstallIn(ApplicationComponent::class)
@Module
object DatabaseModule {

    @Provides
    @Singleton
    fun provideDatabase(@ApplicationContext appContext: Context): AppDatabase {
        return Room.databaseBuilder(
            appContext,
            AppDatabase::class.java,
            "logging.db"
        ).build()
    }

    @Provides
    fun provideLogDao(database: AppDatabase): LogDao {
        return database.logDao()
    }
}
它的编译和运行没有错误。
但是,我使用调试来观察记录器及其得到的。
Method threw 'kotlin.UninitializedPropertyAccessException' exception.
我在运行时调用 logger.something() 它的抛出
Fatal Exception: kotlin.UninitializedPropertyAccessException
lateinit property logger has not been initialized
更多信息
https://dagger.dev/hilt/migration-guide.html
https://codelabs.developers.google.com/codelabs/android-hilt#10
https://medium.com/mobile-app-development-publication/injecting-viewmodel-with-dagger-hilt-54ca2e433865

最佳答案

由于 LoggerDataSource 是一个接口(interface),我们需要指定我们需要注入(inject)的实现。感谢@Andrew 提供注入(inject)构造函数的想法

class RecordFragmentViewModel
@ViewModelInject
constructor(@Assisted private val savedStateHandle: SavedStateHandle,
            @DatabaseLogger private val logger: LoggerDataSource) :
    ViewModel(), LifecycleObserver {
指定
@Qualifier
annotation class InMemoryLogger

@Qualifier
annotation class DatabaseLogger

@InstallIn(ApplicationComponent::class)
@Module
abstract class LoggingDatabaseModule {

    @DatabaseLogger
    @Singleton
    @Binds
    abstract fun bindDatabaseLogger(impl: LoggerLocalDataSource): LoggerDataSource
}

@InstallIn(ActivityComponent::class)
@Module
abstract class LoggingInMemoryModule {

    @InMemoryLogger
    @ActivityScoped
    @Binds
    abstract fun bindInMemoryLogger(impl: LoggerInMemoryDataSource): LoggerDataSource
}

关于ViewModel中的Android Hilt Dagger 注入(inject)接口(interface)@ViewModelInject得到了UninitializedPropertyAccessException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65540035/

相关文章:

android - 为 Android WebView 启用调试是否有任何缺点?

android - 如何在 Android 应用程序中共享 LiveData 实例?

C# - IoC - WebAPI 2 上的 Autofac 依赖注入(inject)

android - 在前台服务中实现 Room 时的 ViewModel

android - MutableLiveData<Pair<Float, Float>>() -> Val 不能被重新赋值

android - Canvas 上的鼠标单击(或触摸)事件导致使用 HTML5、Phonegap 和 Android 进行选择

java - 我在 susbstring 管理中遇到错误

android - res/menu 和 res/xml 不存在

android - Dagger2 单例实际上并不是单例问题

c# - 控制反转和内部类