1、Camera Framework 概述:Android相机架构全景
说实话,Android相机框架是我在系统开发中遇到过最复杂的模块之一。它不像你写个普通App,调个API就完事了。相机这东西,涉及硬件、驱动、服务层、应用层,层层嵌套。我刚开始接触时,也被这庞大的架构搞得晕头转向。
但别怕,咱们一步步拆解。今天这一章,就是整个课程的地基。地基打牢了,后面30章你才能站得稳。
Android相机架构全景
先给你画个全景图。Android相机系统,说白了就是一条流水线:
- 最底层:摄像头硬件传感器(CMOS、ISP)
- 中间层:HAL层(硬件抽象层)+ CameraProvider
- 核心层:CameraService(系统服务)
- 上层:CameraDevice + CameraManager(给App用的API)
- 最顶层:你的App或者系统相机应用
嗯,这里要注意:每一层都有自己独立的进程空间。为什么?因为相机数据量大,而且涉及权限和安全。分层隔离,是Android设计者的智慧。
核心观点:Camera Framework不是单指某个服务,而是从硬件到应用的一整套通信协议和组件集合。你写的App调用的每一个capture(),背后都经历了至少4个进程的协作。
我个人习惯把相机架构比作一个「管道系统」。App是水龙头,CameraService是阀门,CameraProvider是水泵,硬件就是水源。任何一个环节堵了,水就出不来。
Camera Framework 在系统中的位置
你想想看,Android系统里跑着几十个系统服务。ActivityManager管界面,WindowManager管窗口,那CameraService管什么?
说白了,CameraService就是相机世界的「交通警察」。它负责:
- 管理所有摄像头设备的生命周期
- 协调多个App同时访问相机的冲突
- 转发App的请求到HAL层
- 把硬件产生的数据流回传给App
我记得有一次排查线上问题,发现某个App打开相机后一直黑屏。查了半天,原来是CameraService在初始化时,和Provider之间的Binder通信超时了。这种问题,如果你不了解Framework的位置,根本无从下手。
避坑指南:我曾经在调试时发现,CameraService运行在system_server进程里。这意味着如果相机模块崩溃,整个系统服务都会受影响。所以,千万别在CameraService里做耗时操作。
核心组件介绍
1. CameraService
CameraService是Android相机系统的「大脑」。它运行在system_server进程中,以系统服务的形式存在。它的主要职责包括:
- 设备管理:枚举所有摄像头,管理它们的打开/关闭状态
- 权限控制:检查App是否有相机权限
- 会话管理:创建和管理CameraDeviceSession
- 数据分发:把HAL层返回的帧数据分发给对应的App
代码层面,CameraService的核心实现在 frameworks/av/services/camera/libcameraservice/ 目录下。你如果去看源码,会发现它主要继承自 BnCameraService,通过Binder与客户端通信。
// CameraService 的核心接口(简化)
class CameraService : public BnCameraService {
public:
// 打开一个摄像头设备
status_t connect(const sp<ICameraClient>& client,
int cameraId,
/* 输出 */ sp<ICameraDevice>& device);
// 获取摄像头信息列表
status_t getCameraInfo(int cameraId,
struct CameraInfo* cameraInfo);
// 添加/移除摄像头(热插拔)
status_t addCamera(const String16& cameraId);
status_t removeCamera(const String16& cameraId);
};
嗯,这里要注意:CameraService并不直接操作硬件。它只是调度者。真正干活的,是下面的CameraProvider。
2. CameraProvider
CameraProvider是Android 8.0之后引入的组件。它把HAL层独立成了一个单独的进程。为什么这么做?
原因很简单:HAL层是厂商实现的,质量参差不齐。如果HAL崩溃了,不能让它把整个系统服务拖下水。独立进程,意味着HAL挂了,CameraService还能活着。
CameraProvider的核心职责:
- 加载厂商提供的HAL库(如
camera.provider.so) - 实现ICameraProvider接口,暴露给CameraService调用
- 管理底层CameraDevice的创建和销毁
- 处理硬件事件(如闪光灯、对焦、变焦)
注意:CameraProvider和CameraService之间通过HIDL(Android 8~10)或AIDL(Android 11+)通信。如果你在开发中遇到「Service not registered」的错误,多半是Provider进程没启动或者挂了。
我遇到过最坑的一次,是某款手机在低电量时,CameraProvider进程被LMK(Low Memory Killer)给杀了。结果相机App打开后一直卡在「正在启动相机」界面。后来我们在Provider进程里加了前台服务的优先级,才算解决。
3. CameraDevice
CameraDevice是App直接打交道的对象。在Camera2 API中,你通过 CameraManager.openCamera() 获取的就是一个 CameraDevice 实例。
它代表了一个物理或逻辑摄像头。每个CameraDevice可以创建多个 CaptureSession,用来发送拍照或录像请求。
CameraDevice的核心状态机:
| 状态 | 说明 | 常见触发 |
|---|---|---|
| UNINITIALIZED | 未初始化 | 刚创建时 |
| OPENED | 已打开,但未创建会话 | openCamera() 成功后 |
| CONFIGURED | 已配置,可发送请求 | createCaptureSession() 成功后 |
| ERROR | 错误状态 | 硬件异常或断开连接 |
| CLOSED | 已关闭 | close() 调用后 |
你想想看,为什么CameraDevice要设计这么多状态?因为相机硬件是独占资源。如果不做状态管理,两个App同时打开同一个摄像头,那不乱套了?
我个人习惯在调试时,先检查CameraDevice的状态。很多「拍照黑屏」的问题,其实是因为设备处于ERROR状态,但App没有正确处理回调。
// CameraDevice 典型使用流程
CameraManager manager = (CameraManager) getSystemService(CAMERA_SERVICE);
String cameraId = manager.getCameraIdList()[0];
// 打开设备
manager.openCamera(cameraId, new CameraDevice.StateCallback() {
@Override
public void onOpened(@NonNull CameraDevice device) {
// 设备已打开,可以创建会话了
device.createCaptureSession(...);
}
@Override
public void onDisconnected(@NonNull CameraDevice device) {
// 设备断开连接,需要释放资源
device.close();
}
@Override
public void onError(@NonNull CameraDevice device, int error) {
// 出错了!检查 error code
Log.e("Camera", "Error: " + error);
}
}, null);
总结一下:CameraService是调度中心,CameraProvider是硬件代理,CameraDevice是App的接口。三者通过Binder/HIDL串联起来,构成了Android相机框架的骨架。
这一章的内容,说白了就是让你对整个相机架构有个「上帝视角」。后面每一章,我们都会深入其中一个组件,把代码一行行拆开看。但今天,你只要记住这三者的关系和位置就够了。
嗯,我建议你打开Android源码,找到 frameworks/av/services/camera/ 目录,先浏览一下文件结构。不用看懂代码,先感受一下模块的划分。这对后续学习非常有帮助。