Android ViewModel @ViewModelInject 中的 Hilt Dagger 注入接口出现 UninitializedPropertyAccessException
Android Hilt dagger inject interface in viewModel @ViewModelInject got UninitializedPropertyAccessException
我正在试用 Hilt Codelab
https://codelabs.developers.google.com/codelabs/android-hilt#10
它与 Activity 和 Fragment
一起工作正常
logger 是一个 RoomDB
然后我尝试用这个 article
将记录器注入 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
Class 要注入的记录器
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
由于 LoggerDataSource 是一个接口,我们需要指定我们需要注入哪个实现。感谢@Andrew 提出注入构造函数的想法
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
}
我正在试用 Hilt Codelab https://codelabs.developers.google.com/codelabs/android-hilt#10
它与 Activity 和 Fragment
一起工作正常logger 是一个 RoomDB
然后我尝试用这个 article
将记录器注入 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
Class 要注入的记录器
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
由于 LoggerDataSource 是一个接口,我们需要指定我们需要注入哪个实现。感谢@Andrew 提出注入构造函数的想法
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
}