Dagger-Hilt依赖注入失效:repository未初始化问题解决
Hilt ViewModel中repository未初始化的修复方案
问题背景
使用Dagger-Hilt版本2.48,相关代码及报错如下:
AppModule类
@Module @InstallIn(SingletonComponent::class) object AppModule { @Provides @Singleton fun provideDatabase(@ApplicationContext context: Context) = Room.databaseBuilder(context, V2BasketDatabase::class.java, "basket_database") .fallbackToDestructiveMigration() .allowMainThreadQueries() .build() @Provides @Singleton fun provideContext(@ApplicationContext appContext: Context): Context { return appContext } @Provides @Singleton fun provideBasketDao(db: V2BasketDatabase) = db.basketDao() }
ViewModel代码
@HiltViewModel class V2CoffeeShopMenuFragmentViewModel @Inject constructor(application: Application) : BaseViewModel(application) { private lateinit var readAllData: LiveData<List<V2ModelBasket>> @Inject lateinit var repository: V2BasketRepository fun initDb(context: Context) { readAllData = repository.readAllData } fun readProductByProductId(productId: Int): V2ModelBasket? { return if (repository.readProductByProductId(productId) != null) repository.readProductByProductId(productId) else null } }
Fragment中ViewModel使用方式
private val viewModel: V2CoffeeShopMenuFragmentViewModel by viewModels()
报错信息
kotlin.UninitializedPropertyAccessException: lateinit property repository has not been initialized
修复方案
1. 配置Repository的注入绑定
Hilt无法自动初始化V2BasketRepository,核心原因是缺少该类的注入绑定,二选一即可:
- 方案A:给Repository添加@Inject构造函数
让Hilt自动识别并创建实例:
class V2BasketRepository @Inject constructor( private val basketDao: V2BasketDao ) { val readAllData: LiveData<List<V2ModelBasket>> = basketDao.getAllItems() fun readProductByProductId(productId: Int): V2ModelBasket? { return basketDao.getProductById(productId) } }
- 方案B:在AppModule中添加provides方法
手动提供Repository实例:
@Module @InstallIn(SingletonComponent::class) object AppModule { // ... 原有代码 ... @Provides @Singleton fun provideBasketRepository(basketDao: V2BasketDao): V2BasketRepository { return V2BasketRepository(basketDao) } }
2. 修正ViewModel的注入逻辑
ViewModel中不要用@Inject lateinit var延迟注入,直接在构造函数中注入Repository,确保ViewModel创建时依赖已初始化:
@HiltViewModel class V2CoffeeShopMenuFragmentViewModel @Inject constructor( application: Application, private val repository: V2BasketRepository // 构造函数直接注入 ) : BaseViewModel(application) { private lateinit var readAllData: LiveData<List<V2ModelBasket>> init { // 直接初始化数据,无需手动传Context readAllData = repository.readAllData } fun readProductByProductId(productId: Int): V2ModelBasket? { return repository.readProductByProductId(productId) } }
3. 补全Hilt全局配置
- Application类添加@HiltAndroidApp注解
这是Hilt的入口配置:
@HiltAndroidApp class MyApplication : Application() { // 自定义逻辑 }
- Fragment添加@AndroidEntryPoint注解
确保Fragment能获取Hilt的依赖注入能力:
@AndroidEntryPoint class V2CoffeeShopMenuFragment : Fragment() { private val viewModel: V2CoffeeShopMenuFragmentViewModel by viewModels() // 业务逻辑 }
4. 移除冗余的initDb方法
数据库、Dao、Repository的依赖链已通过Hilt自动关联,无需手动传递Context,直接删除initDb方法即可。
内容的提问来源于stack exchange,提问作者Pooya Jannati Poor
相关产品推荐
相关产品推荐

