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

Jetpack Compose页面传参异常:surveyToken传递至ResultScreen报错

解决Jetpack Navigation传参报错问题

问题场景

需要将surveyToken传递到ResultScreen,但运行时抛出找不到导航目的地的错误,相关代码及报错如下:

跳转调用代码

surveyScreen(
    moveToResult = { surveyToken ->
        navController.navigateToResult(surveyToken)
    }
)
const val resultRoute = "result_route"

fun NavController.navigateToResult(surveyToken: String, navOptions: NavOptions? = null) {
    this.navigate("$resultRoute/$SURVEY_TOKEN?=$surveyToken", navOptions)
}

@OptIn(ExperimentalAnimationApi::class)
fun NavGraphBuilder.resultScreen(deviceDisplayState: DeviceDisplayState, moveToOrder: () -> Unit, moveToBack: () -> Unit) {
    composable(route = resultRoute) {
        ResultRoute(deviceDisplayState, moveToOrder, moveToBack, hiltViewModel(LocalContext.current as MainActivity))
    }
}

ResultViewModel代码

@HiltViewModel
class ResultViewModel @Inject constructor(
    savedStateHandle: SavedStateHandle,
    val snackBarMonitor: SnackBarMonitor
) : ViewModel() {
    private val surveyToken: String = checkNotNull(savedStateHandle[SURVEY_TOKEN])
}

报错信息

java.lang.IllegalArgumentException: Navigation destination that matches request NavDeepLinkRequest{ uri=android-app://androidx.navigation/result_route/survey_token?=711d28d33d0fd880459108da5aeb819fce94948f49bdbed20117a27c7109 } cannot be found in the navigation graph NavGraph(0x0) startDestination={NavGraph(0x22fb6594) route=entry_graph startDestination={Destination(0x2395568f) route=entry_route}}

错误原因

  1. 导航路由定义不匹配:resultScreen的composable路由仅定义了result_route,未包含参数占位符,但跳转时使用了带参数的路径,导致Navigation无法匹配到对应的目的地。
  2. 传参格式错误:navigateToResult中拼接的路径格式错误,$resultRoute/$SURVEY_TOKEN?=$surveyToken既不是标准的路径参数格式,也不是查询参数格式,导致生成的URI无法被识别。

解决方案

方案1:使用查询参数传递(推荐)

步骤1:修正导航路由定义

在resultScreen的composable中添加查询参数占位符:

@OptIn(ExperimentalAnimationApi::class)
fun NavGraphBuilder.resultScreen(deviceDisplayState: DeviceDisplayState, moveToOrder: () -> Unit, moveToBack: () -> Unit) {
    // ?后表示参数可选,若需必填可去掉?
    composable(route = "$resultRoute?$SURVEY_TOKEN={$SURVEY_TOKEN}") {
        ResultRoute(deviceDisplayState, moveToOrder, moveToBack, hiltViewModel(LocalContext.current as MainActivity))
    }
}

步骤2:修正navigateToResult函数的路径拼接

使用标准查询参数格式拼接路径:

fun NavController.navigateToResult(surveyToken: String, navOptions: NavOptions? = null) {
    this.navigate("$resultRoute?$SURVEY_TOKEN=$surveyToken", navOptions)
}

方案2:使用路径参数传递

步骤1:修正导航路由定义

将参数作为路径一部分,添加路径参数占位符:

@OptIn(ExperimentalAnimationApi::class)
fun NavGraphBuilder.resultScreen(deviceDisplayState: DeviceDisplayState, moveToOrder: () -> Unit, moveToBack: () -> Unit) {
    composable(route = "$resultRoute/{$SURVEY_TOKEN}") {
        ResultRoute(deviceDisplayState, moveToOrder, moveToBack, hiltViewModel(LocalContext.current as MainActivity))
    }
}

步骤2:修正navigateToResult函数的路径拼接

直接将参数拼接到路径中:

fun NavController.navigateToResult(surveyToken: String, navOptions: NavOptions? = null) {
    this.navigate("$resultRoute/$surveyToken", navOptions)
}

验证参数获取

两种方案中,ResultViewModel通过SavedStateHandle获取参数的代码无需修改,Navigation会自动将路径/查询参数注入到SavedStateHandle中,只需确保SURVEY_TOKEN常量名称和路由中使用的一致即可。

内容的提问来源于stack exchange,提问作者c-an

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 11:28:19