使用Hilt开发时如何向ViewModel传递运行时参数?
解决方案
先解决当前构建错误
- 重复类冲突(core-1.3.2-runtime 与 support-compat-26.1.0-runtime 冲突)
这是旧Android Support库与AndroidX库的兼容问题,按以下步骤修复:- 打开Module级
build.gradle文件,在android块中添加配置:android { ... defaultConfig { ... multiDexEnabled true } // 新增Jetifier配置,自动转换旧Support库依赖为AndroidX gradleProperties { android.useAndroidX = true android.enableJetifier = true } } - 全局替换项目中所有
com.android.support:xxx开头的依赖为对应的AndroidX版本,例如com.android.support:support-compat替换为androidx.core:core-ktx:1.12.0。
- 打开Module级
- kapt NonExistentClass 注解转换错误
这是因为你混用了废弃的@ViewModelInject、字段注入,且缺少对应注解的依赖导致,先清除错误的ViewModel写法,按下方正确方案实现即可解决。
正确实现Hilt ViewModel运行时传参
当前Hilt官方推荐使用@AssistedInject实现带运行时参数的ViewModel注入,不需要自定义完整Factory,也不需要字段注入,步骤如下:
步骤1:统一Hilt依赖版本
确保项目中所有Hilt依赖版本一致,推荐使用2.44及以上稳定版,Module级build.gradle依赖配置参考:
dependencies { implementation "com.google.dagger:hilt-android:2.44" kapt "com.google.dagger:hilt-android-compiler:2.44" }
注意:2.38及以上版本的Hilt已经内置AssistedInject能力,不需要额外引入assisted相关依赖,也不需要AssistedModule配置,你之前遇到的AssistedModule无法解析是因为参考了旧版本的过时方案。
步骤2:改造ViewModel定义
用@AssistedInject代替废弃的@ViewModelInject,运行时参数用@Assisted注解标注,同时定义AssistedFactory:
class FilterByCategoryViewModel @AssistedInject constructor( // Hilt自动注入由ApplicationModule提供的依赖 private val dataManager: AppDataManager, private val networkHelper: NetworkHelper, // 标注为运行时传入的参数 @Assisted private val category: String ) : ViewModel() { // 此处不需要字段注入,所有依赖都通过构造函数传入 // 定义Hilt自动实现的Factory接口 @AssistedFactory interface Factory { fun create(category: String): FilterByCategoryViewModel } }
步骤3:Activity/Fragment中实例化ViewModel
首先确保你的Activity/Fragment添加了@AndroidEntryPoint注解,然后通过注入的Factory创建ViewModel即可:
@AndroidEntryPoint class FilterByCategoryFragment : Fragment() { // 注入Hilt自动生成的Factory @Inject lateinit var viewModelFactory: FilterByCategoryViewModel.Factory // 实例化ViewModel,传入运行时的category参数 private val filterViewModel: FilterByCategoryViewModel by viewModels { val category = "你需要传入的运行时分类值" // 也可以从arguments/Intent中读取 object : ViewModelProvider.Factory { override fun <T : ViewModel> create(modelClass: Class<T>): T { @Suppress("UNCHECKED_CAST") return viewModelFactory.create(category) as T } } } // 后续正常使用filterViewModel即可 }
原有写法错误说明
- 自定义Factory时仅传入了category参数,没有将Hilt管理的
dataManager、networkHelper传入ViewModel实例,就算编译通过,运行时也会出现依赖缺失的问题。 - ViewModel的字段注入不会生效:你自定义Factory创建的ViewModel实例没有经过Hilt的注入流程,
@Inject标注的lateinit字段不会被赋值,会触发未初始化异常。 @ViewModelInject已经在高版本Hilt中被废弃,会触发编译警告甚至错误。
内容的提问来源于stack exchange,提问作者Neeraja Gandla
相关产品推荐
相关产品推荐

