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

Jetpack Compose使用Koin时SavedStateHandle为空该如何排查?

问题原因及修复方案
  • 问题1:getStateViewModel未传入当前导航栈的NavBackStackEntry
    Koin的getStateViewModel需要获取当前路由对应的导航栈实例,才能将导航参数同步到SavedStateHandle中,你直接在DetailScreen的参数默认值调用该方法,无法关联到导航栈的参数。
    修复方法:在composable回调中拿到当前的NavBackStackEntry,主动传入获取ViewModel:
composable(
    Screen.Detail.route,
    arguments = listOf(
        navArgument(Screen.Detail.NAV_ARG) {
            type = NavType.StringType
        }
    )
) { backStackEntry ->
    DetailScreen(
        detailViewModel = getStateViewModel(backStackEntry),
        onBack = actions.goBack
    )
}

同时可以去掉DetailScreen参数里的默认值,避免误用:

@Composable
fun DetailScreen(
    detailViewModel: DetailViewModel,
    onBack: () -> Unit,
) {
    // 页面逻辑
}
  • 问题2:参数键不匹配
    确认你定义的Screen.Detail.NAV_ARG常量值和ViewModel中取值的键一致,你当前ViewModel里硬编码使用"id"作为键,如果Screen.Detail.NAV_ARG的值不是"id",就会取不到值。
    建议统一使用常量避免写错:
class DetailViewModel(
    savedStateHandle: SavedStateHandle,
    private val repository: Repository
) : ViewModel() {
    private val id: String = savedStateHandle.get<String>(Screen.Detail.NAV_ARG) ?: error("id must be available")
}
  • 问题3:路由配置缺少参数占位符
    确认你的Screen.Detail.route定义包含对应参数的占位符,示例如下:
object Screen {
    object Detail {
        const val NAV_ARG = "id"
        val route = "detail/{$NAV_ARG}"
        // 跳转时调用该方法拼接带参数的路由
        fun buildRoute(id: String) = "detail/$id"
    }
}

跳转页面时必须调用buildRoute传入参数,不能直接使用无参数的route值跳转。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 08:54:02