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

使用Hilt注入SavedStateHandle回传页面结果失效问题

问题原因分析:注入的SavedStateHandle无法获取回传结果

本质是实例不匹配:

  • 通过Hilt注入到ViewModel的SavedStateHandle,是ViewModel自身专属的状态容器,和导航组件的页面栈无关;
  • 而navController.currentBackStackEntry?.savedStateHandle是导航组件中当前页面BackStackEntry对应的状态容器,二者是完全独立的实例。

你回传结果时,是把值设置到了**上一个BackStackEntry的SavedStateHandle**里,ViewModel持有的实例根本没被修改,自然收不到结果。


两种解决方式

方式1:让ViewModel绑定BackStackEntry的SavedStateHandle

修改ViewModel的注入逻辑,让它接收和当前页面BackStackEntry绑定的SavedStateHandle:

@HiltViewModel
class CreatePostViewModel @Inject constructor(
    private val savedStateHandle: SavedStateHandle,
) : ViewModel() {
    
    init {
        viewModelScope.launch {
            savedStateHandle.getStateFlow("result", "").collect {
                Timber.d("Result -> $it")
            }
        }
    }
}

在Compose页面中,创建ViewModel时传入当前BackStackEntry:

fun CreatePostScreen(
    navController: NavController,
    coroutineScope: CoroutineScope,
    snackbarState: SnackbarHostState,
) {
    val backStackEntry = navController.currentBackStackEntry!!
    val viewModel: CreatePostViewModel = hiltViewModel(backStackEntry)
    
    // 原监听逻辑可移除,ViewModel内的collect会自动接收结果
}

方式2:手动传递结果到ViewModel

如果不想修改ViewModel的注入方式,可以在Compose中监听BackStackEntry的SavedStateHandle,拿到结果后主动传递给ViewModel:

fun CreatePostScreen(
    navController: NavController,
    coroutineScope: CoroutineScope,
    snackbarState: SnackbarHostState,
    viewModel: CreatePostViewModel = hiltViewModel(),
) {
    LaunchedEffect(key1 = Unit) {
        navController.currentBackStackEntry?.savedStateHandle?.getStateFlow("result", "")?.collect { result ->
            viewModel.onResultReceived(result)
        }
    }
}

ViewModel中添加处理方法:

fun onResultReceived(result: String) {
    Timber.d("Result -> $result")
    // 后续业务逻辑处理
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 11:24:36