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

Compose NavHost传参至Dagger-Hilt ViewModel空值崩溃问题排查

问题分析与解决方法

核心错误点

你的代码存在三个关键问题,导致argument为空并崩溃:

1. 路由定义缺少参数占位符

ScreenRoutes.AstronautDetailsScreen.route未包含{astronautId}占位符,导航时参数无法被NavHost捕获并传入SavedStateHandle。

修正方式:
修改路由定义,添加参数占位符:

object ScreenRoutes {
    const val AstronautDetailsScreen = "astronaut_details/{astronautId}"
}

2. 跳转页面时未携带参数

跳转到目标页面时,必须在路由后拼接实际的astronautId值,否则参数不会被传递。

修正方式:
跳转代码示例:

navController.navigate(ScreenRoutes.AstronautDetailsScreen.replace("{astronautId}", astronautId.toString()))

或直接拼接:

navController.navigate("astronaut_details/$astronautId")

3. ViewModel注入方式错误

你在NavHost中直接传递astronautDetailsViewModel实例,Hilt无法将当前BackStackEntry的SavedStateHandle关联到该ViewModel,导致ViewModel拿不到参数。

修正方式:
在AstronautDetailScreen内部使用hiltViewModel()获取ViewModel,而非外部传入:

@Composable
fun AstronautDetailScreen() {
    val viewModel: AstronautDetailsViewModel = hiltViewModel()
    val astronautDetails by viewModel.astronautDetails.observeAsState(AstronautDetails())
    // 其他UI逻辑
}

同时简化NavHost中的代码:

composable(
    ScreenRoutes.AstronautDetailsScreen.route,
    arguments = listOf(navArgument("astronautId") { type = NavType.IntType })
) {
    AstronautDetailScreen()
}

额外验证点

  • 确认navArgument的名称"astronautId"与ViewModel中savedStateHandle.get的名称完全一致,包括大小写。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 04:01:55