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

Jetpack Compose导航:通过SavedStateHandle向起始目标ViewModel传参

多Activity架构下导航起始目标ViewModel的参数传递方案

针对你遇到的问题,这里提供两种无需大幅改动现有架构的解决方案,核心都是让Intent中的参数能被ViewModel的SavedStateHandle正确获取:

方案一:将参数拼入起始导航路由(推荐)

这种方式完全贴合导航组件的原生参数传递逻辑,和你在单导航图内的传参方式保持一致,无需修改ViewModel代码。

修改FooActivity的代码,把从Intent拿到的参数直接拼入startDestination的路由字符串中:

@AndroidEntryPoint
class FooActivity : FragmentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 处理参数非空情况,根据业务需求调整默认值或异常抛出逻辑
        val param = intent?.getStringExtra("foo-param") ?: "default-value"

        setContent {
            AppTheme {
                val navController = rememberNavController()
                NavHost(
                    navController = navController,
                    // 将实际参数拼入起始路由,替换占位符
                    startDestination = "foo-route/$param",
                ) {
                    composable(
                        route = "foo-route/{foo-param}",
                        arguments = listOf(
                            navArgument("foo-param") { type = NavType.StringType },
                        ),
                    ) {
                        FooScreen(viewModel = hiltViewModel())
                    }
                }
            }
        }
    }
}

导航组件会自动解析路由中的参数,并将其存入对应导航目标的SavedStateHandle,你的FooViewModel无需任何改动就能正常获取到foo-param。

方案二:手动注入参数到BackStackEntry的SavedStateHandle

如果不想修改起始路由的格式,可以在导航目标的Composable中,手动将Intent参数存入当前BackStackEntry的SavedStateHandle,再初始化ViewModel:

@AndroidEntryPoint
class FooActivity : FragmentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val param = intent?.getStringExtra("foo-param")

        setContent {
            AppTheme {
                val navController = rememberNavController()
                NavHost(
                    navController = navController,
                    startDestination = "foo-route/{foo-param}",
                ) {
                    composable(
                        route = "foo-route/{foo-param}",
                        arguments = listOf(
                            navArgument("foo-param") { type = NavType.StringType },
                        ),
                    ) { backStackEntry ->
                        param?.let {
                            // 将参数手动存入当前导航栈条目SavedStateHandle
                            backStackEntry.savedStateHandle["foo-param"] = it
                        }
                        FooScreen(viewModel = hiltViewModel(backStackEntry = backStackEntry))
                    }
                }
            }
        }
    }
}

这种方式同样能让FooViewModel通过SavedStateHandle获取到参数,适合需要保留路由占位符格式的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 15:33:09