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
相关产品推荐
相关产品推荐

