如何在Android Fragment中使用CameraX API同步关闭相机?
解决CameraX调用unbindAll()后无法同步关闭相机的问题
首先明确:ProcessCameraProvider.unbindAll()本身是异步触发相机关闭操作的,官方文档说明它仅负责触发关闭流程,不会等待操作完成。如果需要确认相机完全关闭或实现同步等待,可以参考以下几种方案:
方法1:监听相机状态回调
CameraX提供了相机状态监听能力,通过监听CameraState的变化可以精准捕获相机关闭完成的时机:
- 绑定用例时保留
Camera实例引用:
// 绑定ImageAnalysis等用例时,获取Camera实例 val camera = cameraProvider.bindToLifecycle( this, // 当前Fragment作为LifecycleOwner cameraSelector, imageAnalysis )
- 注册状态回调监听
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
相关产品推荐
相关产品推荐

