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

如何在Android Fragment中使用CameraX API同步关闭相机?

解决CameraX调用unbindAll()后无法同步关闭相机的问题

首先明确:ProcessCameraProvider.unbindAll()本身是异步触发相机关闭操作的,官方文档说明它仅负责触发关闭流程,不会等待操作完成。如果需要确认相机完全关闭或实现同步等待,可以参考以下几种方案:

方法1:监听相机状态回调

CameraX提供了相机状态监听能力,通过监听CameraState的变化可以精准捕获相机关闭完成的时机:

  1. 绑定用例时保留Camera实例引用:
// 绑定ImageAnalysis等用例时,获取Camera实例
val camera = cameraProvider.bindToLifecycle(
    this, // 当前Fragment作为LifecycleOwner
    cameraSelector,
    imageAnalysis
)
  1. 注册状态回调监听CLOSED状态:
camera.cameraInfo.cameraState.observe(this) { cameraState ->
    if (cameraState.type == CameraState.Type.CLOSED) {
        // 相机已完全关闭,在这里执行需要等待关闭完成的逻辑
    }
}

调用unbindAll()后,相机状态会依次从OPEN→CLOSING→CLOSED,触发回调时即可确认关闭完成。

方法2:用CountDownLatch实现同步等待(慎用)

如果确实需要在代码中同步阻塞等待相机关闭(禁止在主线程执行,避免ANR),可以借助CountDownLatch:

override fun onPause() {
    super.onPause()
    val latch = CountDownLatch(1)
    
    // 获取当前绑定的相机实例
    val camera = cameraProvider.getBoundCameraInfos().firstOrNull()?.camera
    camera?.cameraInfo?.cameraState?.observe(this) { state ->
        if (state.type == CameraState.Type.CLOSED) {
            latch.countDown()
        }
    }
    
    cameraProvider.unbindAll()
    
    // 设置超时时间,避免无限等待
    try {
        latch.await(2, TimeUnit.SECONDS)
    } catch (e: InterruptedException) {
        Thread.currentThread().interrupt()
    }
    
    // 相机关闭完成(或超时),继续后续逻辑
}

方法3:依托Fragment生命周期监听

CameraX与Fragment生命周期强绑定,当Fragment进入ON_STOP状态时,相机通常已完成关闭:

lifecycle.addObserver(object : DefaultLifecycleObserver {
    override fun onStop(owner: LifecycleOwner) {
        super.onStop(owner)
        // 此时相机已完成关闭,执行后续逻辑
        lifecycle.removeObserver(this)
    }
})

补充提示

unbindAll()触发的关闭操作通常耗时极短(几十毫秒级别),多数场景下无需刻意等待。如果必须做状态确认,优先选择方法1的状态回调,这是最贴合CameraX设计逻辑的实现方式,避免线程阻塞风险。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 00:52:13