Android CameraX Fragment切后台恢复后预览黑屏/不可见问题
CameraX前后台切换预览黑屏问题排查
你的实现存在以下几个明确问题,是导致偶现黑屏的核心原因:
- Preview与SurfaceProvider绑定逻辑有缺陷
你在执行bindToLifecycle前就给Preview设置了SurfaceProvider,当应用切到后台时,PreviewView的渲染Surface会被系统销毁回收,切回前台时PreviewView会生成全新的Surface,但你持有的Preview实例仍然关联着已经失效的旧Surface,自然无法输出画面。CameraX的生命周期自动绑定只会管理相机硬件的启停,不会自动为已创建的Preview实例重新关联新生成的Surface。 - 前后台切换的生命周期处理逻辑缺失
你把onResume方法中原本的startCamera()调用注释掉了,同时onPause中没有做任何状态校验与资源处理。不少国产ROM会在应用进入后台时强制抢占相机硬件资源,CameraX自带的生命周期绑定在这类系统上存在偶现的重连失败问题,没有主动在回到前台时校验相机状态、重新绑定用例的话,就会出现相机启动失败的黑屏。 - 后台状态下视频录制未停止,阻塞预览通道
代码没有在onPause回调中判断isRecording状态并停止录制。如果切后台时正处于视频录制过程中,VideoCapture会持续占用相机输出通道,多数系统会禁止应用在后台状态下访问相机,切回前台时录制状态异常卡住,会直接阻塞预览流的输出。 - 屏幕旋转参数仅初始化一次,未动态更新
你在首次绑定UseCase时仅获取了一次屏幕旋转角度设置给ImageCapture和VideoCapture,当应用在后台时如果发生屏幕方向变化(比如用户开启自动旋转后切横竖屏),切回前台时UseCase配置的目标旋转角度和实际屏幕方向不匹配,部分机型上会直接触发预览渲染异常导致黑屏。 - 资源未正确释放,累积触发异常
你初始化的单线程executor没有在Fragment销毁时调用shutdown(),自定义的人脸检测器faceDetector也没有在生命周期结束时释放资源,多次前后台切换后资源堆积会阻塞帧处理流程,导致预览卡死黑屏。 - 重复配置CameraSelector触发绑定异常
你在调用bindToLifecycle时已经传入了统一的CameraSelector,但构建ImageCapture、VideoCapture时又重复调用setCameraSelector()配置镜头方向,部分CameraX版本下重复给UseCase设置CameraSelector会导致生命周期重绑逻辑异常,前后台切换时UseCase无法正常恢复。
对应修复方案
- 调整SurfaceProvider绑定时机:将
preview.setSurfaceProvider(binding.preview.getSurfaceProvider())的调用移到bindToLifecycle执行成功之后,同时监听PreviewView的Surface状态,每次Surface重建时都重新给当前Preview实例设置SurfaceProvider。 - 补全生命周期处理逻辑:在
onResume中增加相机状态校验,如果当前相机实例未正常工作则重新执行绑定逻辑;在onPause中如果处于录制状态先调用stopVideoRecording()停止录制,释放相机通道。 - 增加旋转方向动态更新:监听屏幕方向变化,每次方向变更时给所有已创建的UseCase更新
targetRotation参数,无需重新绑定即可适配方向变化。 - 补全资源释放逻辑:在
onDestroy回调中关闭自定义的executor、释放人脸检测器资源,同时获取ProcessCameraProvider实例执行unbindAll()彻底释放相机资源。 - 移除ImageCapture、VideoCapture构建时重复的
setCameraSelector()调用,统一在bindToLifecycle时传入镜头选择配置,避免重复配置导致的绑定异常。
内容的提问来源于stack exchange,提问作者cubesoft
相关产品推荐
相关产品推荐

