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

使用AssistedInjection时,如何让Hilt识别ViewModel并作用域化依赖?

问题:带自定义参数的ViewModel如何让Hilt识别为Hilt ViewModel?

我正在创建一个构造函数包含非传递依赖参数的ViewModel,示例代码如下:

class MyViewModel(
    private val fetchUserUseCase: FetchUserUseCase,
    private val fetchNewsUseCase: FetchNewsUseCase,
    myCustomParameter: String = "",
    myOtherCustomParameter: Long = -1L
) : ViewModel()

由于最后两个自定义参数,我无法使用@HiltViewModel注解。当使用@AssistedInjection创建自定义ViewModel Factory时,尝试将FetchNewsUseCase作用域标记为@ViewModelScoped,会出现错误:

error: [Dagger/MissingBinding] FetchNewsUseCase cannot be provided without an @Provides-annotated method.

请问如何让Hilt/Dagger将MyViewModel识别为“Hilt ViewModel”?


解决方案

要让带自定义参数的ViewModel被Hilt正确处理,需结合@AssistedInject、@Assisted及自定义Factory,同时正确配置依赖的作用域与提供方式,具体步骤如下:

1. 改造ViewModel构造函数

将自定义参数标记为@Assisted,并使用@AssistedInject替代默认构造,同时定义配套的@AssistedFactory接口:

class MyViewModel @AssistedInject constructor(
    private val fetchUserUseCase: FetchUserUseCase,
    private val fetchNewsUseCase: FetchNewsUseCase,
    @Assisted private val myCustomParameter: String,
    @Assisted private val myOtherCustomParameter: Long
) : ViewModel() {
    @AssistedFactory
    interface Factory {
        fun create(myCustomParameter: String, myOtherCustomParameter: Long): MyViewModel
    }
}

2. 配置@ViewModelScoped依赖的绑定

若FetchNewsUseCase标记了@ViewModelScoped,需确保它有合法的实例提供方式:

  • 构造注入方式:为FetchNewsUseCase的构造函数添加@Inject注解,同时指定作用域:
@ViewModelScoped
class FetchNewsUseCase @Inject constructor(
    // 此处传入该用例的依赖项
) {
    // 业务逻辑实现
}
  • 模块提供方式:在Hilt模块中添加@Provides方法,指定作用域并关联ViewModelComponent:
@Module
@InstallIn(ViewModelComponent::class)
object UseCaseModule {
    @Provides
    @ViewModelScoped
    fun provideFetchNewsUseCase(): FetchNewsUseCase {
        return FetchNewsUseCase(/* 传入依赖参数 */)
    }
}

注意:@ViewModelScoped的依赖必须安装在ViewModelComponent中,才能让Hilt在ViewModel作用域内提供实例。

3. 在页面中获取ViewModel实例

在Activity或Fragment中,通过Hilt注入自定义Factory,再结合viewModels()委托获取ViewModel:

class MyActivity : AppCompatActivity() {
    @Inject
    lateinit var myViewModelFactory: MyViewModel.Factory

    private val viewModel: MyViewModel by viewModels {
        myViewModelFactory.create("自定义字符串参数", 123L)
    }

    // 页面其他逻辑
}

关键注意事项

  • 禁止混用@HiltViewModel与@AssistedInject:@HiltViewModel仅适用于无自定义参数的ViewModel,带自定义参数必须使用@AssistedInject+@AssistedFactory组合。
  • 确保依赖作用域与组件匹配:@ViewModelScoped依赖的模块必须@InstallIn(ViewModelComponent::class),否则Hilt无法识别作用域。
  • 所有依赖需有明确绑定:无论是构造注入还是模块提供,必须让Dagger能找到对应的实例生成逻辑,避免MissingBinding错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 21:15:11