Android Camera2 API捕获图像报CaptureRequest含未配置Surface错误
错误核心原因
堆栈中抛出的IllegalArgumentException: CaptureRequest contains unconfigured Input/Output Surface!本质是Camera2 API的一致性校验逻辑触发的,和你在源码里看到的逻辑一致:系统会将CaptureRequest里的每个Surface映射为对应的硬件流ID,只要这个Surface没有提前在CaptureSession创建时注册为合法输出目标,就会在convertSurfaceToStreamId阶段找不到对应流,直接抛出异常。
对照你的实现代码,存在3个明确的逻辑问题:
- 创建
CameraCaptureSession时,传入的输出列表只有previewSurface,没有把ImageReader对应的recordingSurface加入会话配置。但后续构建预览CaptureRequest时,却给请求添加了recordingSurface作为输出目标,完全违反了API的校验规则。 - ImageReader的监听器存在嵌套套娃的冗余逻辑:第一次设置的
OnImageAvailableListener回调里,又重新给ImageReader设置了一次监听器,这个逻辑既没有实际作用,还会导致监听器重复绑定。 - 硬编码取
cameraIdList[1]作为目标摄像头,没有判断设备实际支持的摄像头数量,存在数组越界崩溃的风险。
修复方案
按照Camera2的API规则调整逻辑,具体修改点如下:
- 构建会话输出列表时,将所有后续要在CaptureRequest中使用的Surface全部传入,保证会话注册的输出目标和请求使用的目标完全匹配。
- 构建预览CaptureRequest时,对应加入所有会话已注册的Surface作为输出target,不要使用未注册的Surface。
- 移除嵌套的ImageReader监听器逻辑,在ImageReader初始化阶段就一次性配置好图像可用回调,同时记得在处理完Image资源后主动调用
close(),避免内存泄漏。 - 增加摄像头列表的边界判断,根据业务需要选择匹配的摄像头ID,避免硬编码数组索引导致的越界问题。
修正后的核心逻辑参考:
// 1. 初始化ImageReader时直接配置监听器,移除嵌套逻辑 val imageReader = ImageReader.newInstance(rotatedPreviewWidth, rotatedPreviewHeight, ImageFormat.YUV_420_888, 2) imageReader.setOnImageAvailableListener({ reader -> reader.acquireLatestImage()?.use { image -> Log.d("camera", "receive image frame") // 图像处理逻辑 } }, Handler { true }) val previewSurface = surfaceView.holder.surface val recordingSurface = imageReader.surface val captureCallback = object : CameraCaptureSession.StateCallback() { override fun onConfigureFailed(session: CameraCaptureSession) {} override fun onConfigured(session: CameraCaptureSession) { // 2. 构建预览请求时,添加所有已在会话中注册的Surface val previewRequestBuilder = cameraDevice.createCaptureRequest(TEMPLATE_PREVIEW).apply { addTarget(previewSurface) addTarget(recordingSurface) } session.setRepeatingRequest( previewRequestBuilder.build(), object : CameraCaptureSession.CaptureCallback() {}, Handler { true } ) } } // 3. 创建会话时,将所有需要的Surface全部加入输出列表,不要漏传recordingSurface cameraDevice.createCaptureSession(listOf(previewSurface, recordingSurface), captureCallback, Handler { true })
注意:Camera2 API对Surface的匹配有严格的校验规则,所有添加到CaptureRequest中的Surface,必须在会话创建阶段就完成注册,否则无论后续如何调整请求参数,都会触发该类异常。
内容的提问来源于stack exchange,提问作者Hamza Khurshid
相关产品推荐
相关产品推荐

