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
相关产品推荐
相关产品推荐

