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

使用Hilt传递运行时参数实例化ViewModel并在init块触发接口请求

解决方案

下面提供两种可落地的实现方式,可根据你的业务需求选择:

方案一:最简实现(推荐大部分场景使用)

不需要修改ViewModel构造参数,也无需自定义工厂,直接在Activity获取到授权码后调用ViewModel的方法即可,逻辑清晰维护成本低:

@AndroidEntryPoint
class MainActivity : ComponentActivity() {
    private val viewModel : MainActivityViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 提取授权码
        val authCode = intent.data?.getQueryParameter("code")
        authCode?.let {
            viewModel.getAccessToken(it)
        } ?: run {
            // 自行处理授权码为空的异常逻辑,比如跳转授权页、提示错误等
        }
        // 其他初始化逻辑
    }
}

方案二:通过Hilt辅助注入实现构造传参(满足init块调用需求)

如果你确实需要在ViewModel的init初始化块中执行请求逻辑,可以使用Hilt提供的辅助注入(Assisted Inject)能力传递动态参数:

步骤1:改造ViewModel定义

// 声明辅助工厂
@HiltViewModel(assistedFactory = MainActivityViewModel.Factory::class)
class MainActivityViewModel @AssistedInject constructor(
    private val repository: AuthRepository,
    // 动态参数加@Assisted注解
    @Assisted private val authCode: String
) : ViewModel() {

    interface Factory {
        fun create(authCode: String): MainActivityViewModel
    }

    init {
        // 初始化阶段直接调用请求方法
        getAccessToken(authCode)
    }

    fun getAccessToken(authCode: String) {
        // 原有请求逻辑
    }
}

步骤2:改造Activity中ViewModel的获取逻辑

@AndroidEntryPoint
class MainActivity : ComponentActivity() {
    private val viewModel : MainActivityViewModel by viewModels {
        object : ViewModelProvider.Factory {
            override fun <T : ViewModel> create(modelClass: Class<T>): T {
                val authCode = intent.data?.getQueryParameter("code") ?: error("缺少必要的授权码参数")
                // 调用Hilt辅助工厂传入授权码生成ViewModel实例
                return hiltViewModelFactory<MainActivityViewModel, MainActivityViewModel.Factory>(
                    factoryClass = MainActivityViewModel.Factory::class
                ) { factory ->
                    factory.create(authCode)
                } as T
            }
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 其他初始化逻辑
    }
}

关于SavedStateHandle的疑问解答

默认情况下SavedStateHandle只能读取Intent的extras Bundle中的数据,无法直接读取intent.data里的查询参数。如果你想通过SavedStateHandle传递参数,还是需要先在Activity中提取出授权码后手动存入SavedStateHandle,本质和方案一逻辑一致,没有额外优势,因此不推荐。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 23:09:02