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 层的数据流路径。

Camera2 核心架构分层与数据流 应用层(App Layer) CameraManager · CameraDevice · CameraCaptureSession 框架层(Framework Layer) CameraService · CameraProvider · 管道抽象 HAL 层(Hardware Abstraction Layer) Camera HAL · 传感器驱动 · ISP 管道 关键数据流路径 App → CaptureRequest → CameraService → HAL → 传感器 → 图像数据 → 回调/输出 Surface

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 生命周期状态机 IDLE(空闲) openCamera() OPENING(打开中) onOpened() OPENED(已打开) close() CLOSED(已关闭) onError() onDisconnected() ERROR / DISCONNECTED 注意:CameraDevice 是重量级资源,必须在使用完毕后显式调用 close() 释放,否则会导致其他应用无法打开相机。

在 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。

创建会话的典型流程如下:

  1. 准备输出 Surface:为预览、拍照、录像等用途创建对应的 Surface 对象。
  2. 调用 createCaptureSession:cameraDevice.createCaptureSession(outputSurfaces, callback, handler)。
  3. 等待 onConfigured:会话配置成功后,在 CameraCaptureSession.StateCallback.onConfigured() 中开始提交请求。
  4. 提交请求:使用 capture()(单次)或 setRepeatingRequest()(连续)发送 CaptureRequest。
  5. 关闭会话:调用 session.close() 释放管道资源。
常见陷阱: 创建 CameraCaptureSession 时,传入的 outputSurfaces 列表必须与 CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP 中声明的组合兼容。例如,不能同时请求两个不同尺寸的 YUV_420_888 流,除非设备明确支持。不兼容的配置会导致 onConfigureFailed() 回调。

1.6 生命周期协作时序

下图展示了从打开相机到关闭会话的完整时序,帮助理解三个核心角色如何协同工作:

Camera2 核心角色生命周期协作时序 时间 CameraManager getCameraIdList() getCameraCharacteristics() openCamera() CameraDevice onOpened() createCaptureSession() close() CaptureSession onConfigured() capture() setRepeatingRequest() close() 生命周期管理最佳实践 1. CameraManager 在整个应用生命周期内保持单例,避免重复创建。 2. CameraDevice 在 onPause() 中关闭,在 onResume() 中重新打开。 3. CameraCaptureSession 在 CameraDevice 关闭前先关闭,顺序不可颠倒。 4. 所有回调均在 CameraHandler 线程中执行,注意线程安全。

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 最后打开,最先关闭。遵循这个顺序可以避免大部分资源泄漏和状态异常。