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

Android Kotlin如何使用Hilt向BaseActivity等基类注入ViewModel

首先可以明确,基类完全可以和Hilt配合使用,仅需遵守Hilt的入口注解和依赖注入规则即可。

报错根因

你遇到的报错来自两个核心问题:

  • 泛型推导失败:by viewModels<>()未显式指定VM泛型类型,Kotlin无法匹配到对应委托方法,触发方法缺失报错
  • 注入方式错误:Hilt注入ViewModel不能直接使用默认无参viewModels()在抽象基类中直接初始化,需要配合Hilt的生命周期API和子类入口注解实现
正确实现方案

前置依赖确认

先确保项目已经完成Hilt基础配置:

  • Application类添加@HiltAndroidApp注解
  • 已引入Hilt核心、编译器、ViewModel扩展相关依赖

1. 基类实现

抽象基类无需添加Hilt入口注解,调整代码如下:

abstract class BaseActivity<VB: ViewBinding, VM: BaseViewModel>(
    val bindingFactory: (LayoutInflater) -> VB
) : AppCompatActivity() {

    protected lateinit var binding: VB
    // 声明ViewModel变量,由子类初始化
    protected abstract val viewModel: VM

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = bindingFactory.invoke(layoutInflater)
        setContentView(binding.root)
    }
}

2. 子类实现

所有继承BaseActivity的具体实现类必须添加@AndroidEntryPoint注解,通过Hilt提供的viewModels()扩展初始化ViewModel:

@AndroidEntryPoint
class DemoActivity : BaseActivity<ActivityDemoBinding, DemoViewModel>(ActivityDemoBinding::inflate) {
    // 由Hilt自动注入ViewModel实例
    override val viewModel: DemoViewModel by viewModels()

    // 子类业务逻辑
}

3. ViewModel配置

所有需要注入的ViewModel必须添加@HiltViewModel注解,构造函数添加@Inject:

@HiltViewModel
class DemoViewModel @Inject constructor(
    // 可直接注入其他依赖,如仓库、数据源等
    private val demoRepository: DemoRepository
) : BaseViewModel() {
    // ViewModel业务逻辑
}
注意事项
  • 只有具体的Activity、Fragment实现类需要加@AndroidEntryPoint注解,抽象基类无需添加
  • Fragment基类的适配逻辑完全一致,仅需将基类继承自Fragment,子类添加@AndroidEntryPoint注解即可,ViewModel可根据需求选择by viewModels()(Fragment作用域)或by activityViewModels()(宿主Activity作用域)
  • 不要尝试在基类构造函数中直接注入ViewModel,Hilt的ViewModel注入必须通过生命周期扩展函数实现

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 19:15:10