You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Hilt基类字段注入问题:lateinit属性未初始化异常排查

问题原因

你遇到的kotlin.UninitializedPropertyAccessException核心问题是字段注入时机晚于init块执行:

  1. DI框架(如Dagger)创建BaseRepository实例时,会先调用构造函数,紧接着执行init块。
  2. @Inject lateinit var logger的字段注入操作,是在对象完全构造完成后才会执行的步骤。
  3. init块中启动的协程是异步执行的,大概率会在logger完成注入前就进入collectLatest回调,此时访问未初始化的lateinit属性就会抛出异常。
解决方案

推荐使用@PostConstruct注解替代init块,该注解标记的方法会在所有依赖注入完成后才被调用,确保logger已完成初始化:

@Singleton
open class BaseRepository(private val userService: UserService) {
    @Inject lateinit var logger: Logger
    private val scope = CoroutineScope(Dispatchers.Default)
    private var collectionJob: Job? = null

    @PostConstruct
    fun startUserCollection() {
        collectionJob = scope.launch {
            userService.flow.collectLatest {
                logger.setUserId(it?.userId)
            }
        }
    }

    // 可选:添加销毁方法避免协程内存泄漏
    @PreDestroy
    fun cleanupCollection() {
        collectionJob?.cancel()
    }
}

额外说明

如果你的DI框架不支持@PostConstruct,可以尝试将logger改为构造注入并借助DI框架的父类依赖自动注入能力:

@Singleton
open class BaseRepository @Inject constructor(
    private val userService: UserService,
    protected val logger: Logger
) {
    private val scope = CoroutineScope(Dispatchers.Default)
    private var collectionJob: Job? = null

    init {
        collectionJob = scope.launch {
            userService.flow.collectLatest {
                logger.setUserId(it?.userId)
            }
        }
    }
}

// 子类无需手动传递logger,DI框架会自动注入
@Singleton
class HomeRepository @Inject constructor(
    private val homeService: HomeService,
    userService: UserService,
    logger: Logger
) : BaseRepository(userService, logger) {
...
}

不过这种方式仍然需要在子类构造函数中声明logger参数,所以优先推荐@PostConstruct方案,完全不需要修改子类代码,符合你的需求。

内容的提问来源于stack exchange,提问作者rysv

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 05:25:41