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

升级依赖后ViewModel存储拍照Uri无法在Composable中展示图片问题

故障根因与修复方案

核心问题:ViewModel实例化逻辑错误

在SamplePage中直接通过构造函数创建InputViewModel实例,Composable每次重组都会生成全新的ViewModel对象,拍照动作触发界面重组后,原有存储了图片URI的ViewModel实例会被销毁,新实例的image字段自然为空值。
修复方式:改用Jetpack Compose提供的viewModel()扩展函数获取ViewModel实例,保证实例与宿主Activity/Fragment生命周期绑定,不会随界面重建销毁。
修改SamplePage中的ViewModel声明代码:

// 需提前导入依赖:import androidx.lifecycle.viewmodel.compose.viewModel
val inputViewModel: InputViewModel = viewModel()

次要问题:PhotoButton逻辑缺陷

未校验拍照结果

ActivityResultContracts.TakePicture()返回值为Boolean类型,代表拍照是否成功,原有代码无论用户拍照成功还是取消,都会返回URI,会导致无效URI被存入ViewModel。

未持久化文件与URI实例

原有代码中File和URI没有用remember修饰,每次Composable重组都会重新生成实例,可能导致拍照时使用的URI和回调返回的URI不一致。

未授予相机URI写入权限

系统相机默认没有权限写入当前App的FileProvider路径,会导致拍照实际失败,生成空文件。
修复后的PhotoButton完整代码:

@Composable
fun PhotoButton(onValChange: ((String) -> Unit)?){
    val context = LocalContext.current
    // 用remember持久化文件和URI,避免重组时重新生成
    val uri by remember {
        val storageDir: File? = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES)
        val file = File(storageDir, "picFromCamera")
        mutableStateOf(
            FileProvider.getUriForFile(
                context,
                "${context.packageName}.provider",
                file
            )
        )
    }

    val launcher = rememberLauncherForActivityResult(ActivityResultContracts.TakePicture()) { isSuccess ->
        // 仅拍照成功时才返回URI
        if (isSuccess && onValChange != null) {
            onValChange(uri.toString())
        }
    }

    FAB() {
        // 给相机授予URI写入权限
        launcher.launch(uri, ActivityOptions.makeBasic().apply {
            Intent.FLAG_GRANT_WRITE_URI_PERMISSION
        }.toBundle())
    }
}

版本适配:Coil加载组件兼容

如果升级了Coil到2.x版本,原有rememberImagePainter已被废弃,建议替换为新的API避免加载异常:

val painter = rememberAsyncImagePainter(model = image)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 01:18:02