1. Camera2 架构概述:核心角色与生命周期
Camera2 是 Android 平台从 API 21(Android 5.0)开始引入的新一代相机框架,旨在替代已废弃的 Camera1 API。它采用管道(Pipeline)架构,将相机设备抽象为一系列可配置的捕获请求(CaptureRequest)和捕获结果(CaptureResult),为开发者提供了更精细的控制能力,是实现多路流并发与性能调优的基础。
Camera2 架构的核心由三个主要角色构成:CameraManager、CameraDevice 和 CameraCaptureSession。理解它们的职责与生命周期,是掌握后续所有高级主题的前提。
1.1 核心角色职责对比
| 角色 | 职责 | 关键方法 | 生命周期状态 |
|---|---|---|---|
| CameraManager | 系统级相机服务代理,负责枚举可用相机、查询特性、打开相机 | getCameraIdList(), getCameraCharacteristics(), openCamera() |
应用进程生命周期 |
| CameraDevice | 代表单个物理相机设备,负责创建捕获会话、提交请求 | createCaptureSession(), createCaptureRequest() |
从打开到关闭(onOpened → onDisconnected/onError) |
| CameraCaptureSession | 管理一组输出 Surface 的捕获管道,负责请求排队与结果回调 | capture(), setRepeatingRequest(), abortCaptures() |
从配置完成到关闭(onConfigured → onClosed) |
1.2 架构分层与数据流
下图展示了 Camera2 架构中三个核心角色之间的协作关系,以及从应用层到 HAL 层的数据流路径。
1.3 CameraManager:相机系统的入口
CameraManager 是应用与相机子系统交互的起点。通过 Context.getSystemService(Context.CAMERA_SERVICE) 获取单例实例,负责以下核心任务:
- 枚举相机:
getCameraIdList()返回所有可用相机 ID(包括前置、后置、外接 USB 相机)。 - 查询特性:
getCameraCharacteristics(cameraId)返回相机的静态信息,如传感器方向、支持的分辨率列表、AE/AWB 范围、REQUEST_AVAILABLE_CAPABILITIES等。 - 打开相机:
openCamera(cameraId, stateCallback, handler)异步打开指定相机,成功后通过回调返回CameraDevice实例。
性能提示: CameraManager 的操作是轻量级的,但
getCameraCharacteristics() 返回的 CameraCharacteristics 对象包含大量元数据,建议在后台线程缓存关键特性(如 SCALER_STREAM_CONFIGURATION_MAP),避免在主线程重复查询。
1.4 CameraDevice:相机设备的抽象
CameraDevice 代表一个已打开的物理相机设备。它的生命周期严格遵循以下状态机:
在 CameraDevice.StateCallback 中,开发者需要实现以下回调:
onOpened(CameraDevice camera):相机成功打开,此时可以创建CameraCaptureSession。onDisconnected(CameraDevice camera):相机被系统强制断开(如被更高优先级的应用抢占),应释放资源。onError(CameraDevice camera, int error):相机发生严重错误,应关闭设备并清理。onClosed(CameraDevice camera):相机已完全关闭,可在此进行最终清理。
1.5 CameraCaptureSession:捕获会话的核心
CameraCaptureSession 是实际执行图像捕获的管道。它管理一组输出 Surface(如 SurfaceView、ImageReader、MediaRecorder 的 Surface),并负责将 CaptureRequest 排队发送到相机 HAL。
创建会话的典型流程如下:
- 准备输出 Surface:为预览、拍照、录像等用途创建对应的
Surface对象。 - 调用 createCaptureSession:
cameraDevice.createCaptureSession(outputSurfaces, callback, handler)。 - 等待 onConfigured:会话配置成功后,在
CameraCaptureSession.StateCallback.onConfigured()中开始提交请求。 - 提交请求:使用
capture()(单次)或setRepeatingRequest()(连续)发送CaptureRequest。 - 关闭会话:调用
session.close()释放管道资源。
常见陷阱: 创建
CameraCaptureSession 时,传入的 outputSurfaces 列表必须与 CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP 中声明的组合兼容。例如,不能同时请求两个不同尺寸的 YUV_420_888 流,除非设备明确支持。不兼容的配置会导致 onConfigureFailed() 回调。
1.6 生命周期协作时序
下图展示了从打开相机到关闭会话的完整时序,帮助理解三个核心角色如何协同工作:
1.7 关键生命周期规则总结
| 操作 | 前置条件 | 后置条件 | 注意事项 |
|---|---|---|---|
openCamera() |
CameraManager 已获取 | CameraDevice 进入 OPENED 状态 | 需在后台线程调用,避免阻塞 UI |
createCaptureSession() |
CameraDevice 处于 OPENED 状态 | CameraCaptureSession 进入 CONFIGURED 状态 | 输出 Surface 列表必须兼容 |
capture() / setRepeatingRequest() |
CameraCaptureSession 已配置 | 捕获请求进入管道队列 | 重复请求会持续发送,直到被替换或停止 |
session.close() |
会话正在运行或空闲 | 会话进入 CLOSED 状态 | 关闭后不可再提交请求 |
cameraDevice.close() |
所有会话已关闭 | CameraDevice 进入 CLOSED 状态 | 必须先关闭会话,再关闭设备 |
核心要点: Camera2 的生命周期管理可以概括为“先开后关,后开先关”。CameraManager 最先获取,最后释放;CameraDevice 在 Manager 之后打开,在 Session 之后关闭;CameraCaptureSession 最后打开,最先关闭。遵循这个顺序可以避免大部分资源泄漏和状态异常。