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

Jetpack Compose+CameraX:导航时如何持久化Bitmap图像状态?

解决Jetpack Compose相机返回后URI丢失的问题

问题分析

你遇到的核心问题是:从相机界面返回后,capturedImageUri短暂有值后变为null,导致图像消失。根源在于:

  • 用NavController.currentBackStackEntry作为LaunchedEffect的触发key,导航返回后组件重组会重复执行LaunchedEffect,此时savedStateHandle中的值已被读取,再次调用get会返回null;
  • 错误地在View层用rememberSaveable维护状态,没有利用ViewModel的生命周期优势来持久化数据。

解决方案

1. 完善ViewModel的状态更新逻辑

确保ViewModel通过viewModel()函数获取(保证其生命周期与导航图/宿主一致),并正确实现状态更新方法:

class PixelConvertViewModel : ViewModel() {
    var originImageUri = mutableStateOf<Uri?>(null)
        private set

    fun saveOriginUrl(uri: Uri) {
        originImageUri.value = uri
    }
}

2. 调整LaunchedEffect的触发逻辑

改用getAndRemove获取savedStateHandle中的值,确保只读取一次,避免重组时重复读取导致null:

LaunchedEffect(Unit) {
    navController.currentBackStackEntry?.savedStateHandle?.getAndRemove<Uri>("capturedImageUri")?.let {
        pixelConvertViewModel.saveOriginUrl(it)
    }
}

或者通过监听StateFlow处理,确保只响应有效的URI:

LaunchedEffect(navController.currentBackStackEntry) {
    val backStackEntry = navController.currentBackStackEntry ?: return@LaunchedEffect
    backStackEntry.savedStateHandle.getStateFlow<Uri?>("capturedImageUri")
        .collect { uri ->
            uri?.let {
                pixelConvertViewModel.saveOriginUrl(it)
                // 移除已处理的URI,避免重复收集
                backStackEntry.savedStateHandle.remove<Uri>("capturedImageUri")
            }
        }
}

3. 正确在View层绑定ViewModel状态

直接使用ViewModel中的状态,不要在View层单独维护rememberSaveable变量——ViewModel的生命周期更长,能跨配置变化和导航持久化数据:

// 获取当前导航图的ViewModel
val pixelConvertViewModel: PixelConvertViewModel = viewModel()
// 直接观察ViewModel的状态
val capturedImageUri by pixelConvertViewModel.originImageUri

// 加载并显示图像示例
capturedImageUri?.let { uri ->
    AsyncImage(model = uri, contentDescription = "Captured image")
}

4. 检查相机界面的返回逻辑

确保相机界面返回时,将URI设置给上一个回退栈条目savedStateHandle:

// 相机界面拍摄完成后返回
navController.previousBackStackEntry?.savedStateHandle?.set("capturedImageUri", capturedUri)
navController.popBackStack()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 17:23:14