2. Android系统架构概览
理解 Android 系统架构,是掌握 HAL 与 Treble 的起点。Android 并不是一个“大而全”的单体系统,而是由多个层次协作组成的软件栈:上层是面向开发者的应用框架,中间是承载系统能力的系统服务与原生库,下层是连接硬件与系统的 HAL,最底层则是 Linux 内核与设备驱动。HAL 正好位于“系统服务/框架”与“内核/驱动”之间,是软硬件解耦的关键接缝。
一、分层结构:从应用到硬件的纵向视角
从纵向看,Android 系统大致可分为五层。最上层是应用层,包括系统应用与第三方应用,它们通过 Android SDK 调用框架 API。第二层是应用框架层,提供 ActivityManager、WindowManager、CameraManager 等 Java/Kotlin API,是开发者最熟悉的编程接口。第三层是系统服务与原生库层,包含以 system_server 为核心的系统服务,以及 SurfaceFlinger、AudioFlinger、MediaCodec 等 C/C++ 原生服务。第四层是HAL 层,以模块或 AIDL/HIDL 接口形式向上提供硬件抽象能力。第五层是Linux 内核与驱动层,负责进程调度、内存管理、电源管理,以及显示、音频、摄像头、传感器等设备驱动。
这种分层不是简单的“上下调用”,而是通过 Binder、HIDL、AIDL、JNI 等机制进行跨进程、跨语言通信。例如,应用调用 CameraManager 打开相机,请求会经过 CameraService,再通过 HAL 接口下发到 Camera HAL,最终由内核中的摄像头驱动操作硬件。
二、HAL 在系统中的位置与作用
HAL(Hardware Abstraction Layer,硬件抽象层)是 Android 为屏蔽硬件差异而设计的一层接口。它向上为系统服务提供统一的硬件访问接口,向下调用内核驱动完成实际硬件操作。HAL 的核心价值在于:让 Android 框架不依赖具体硬件实现,从而支持不同厂商、不同芯片平台的设备。
在传统 Android 中,HAL 多以 hw_get_module() 加载的 .so 模块形式存在,接口定义在 hardware/libhardware/include/hardware/ 下。例如 Camera HAL 需要实现 camera_module_t 与 camera_device_t。在 Treble 之后,HAL 被拆分为 HIDL/AIDL 接口,运行在独立进程中,通过 Binder 化通信与系统服务交互,从而实现框架与 HAL 的独立升级。
HAL 的三大作用:
- 抽象硬件差异:不同厂商的摄像头、音频编解码器、传感器,对上层呈现统一接口。
- 隔离框架与驱动:框架不直接操作
/dev节点,而是通过 HAL 间接访问。 - 支持独立升级:Treble 后 HAL 以稳定接口发布,框架与 HAL 可分别更新。
三、一次相机拍照请求的跨层流程
以“应用调用相机拍照”为例,可以清晰看到各层如何协作:
- 应用层调用
CameraManager.openCamera(),请求进入应用框架层。 - 框架层通过 Binder 将请求发送到
cameraserver中的 CameraService。 - CameraService 通过 HIDL/AIDL 接口调用 Camera HAL 的
open()、configureStreams()。 - Camera HAL 调用内核 V4L2 驱动,配置摄像头传感器与 ISP。
- 图像数据由驱动写入缓冲区,经 HAL 回传到 CameraService,再通过 Surface 显示或编码保存。
这条链路中,HAL 是承上启下的关键节点。若 HAL 接口不稳定,框架升级就会牵动驱动;若 HAL 实现有误,相机可能黑屏、花屏或无法打开。
四、各层职责与典型对象对照
| 层次 | 典型对象/模块 | 主要职责 | 对外接口 |
|---|---|---|---|
| 应用层 | Camera、Settings、第三方 App | 面向用户提供功能 | Android SDK API |
| 应用框架层 | ActivityManager、CameraManager | 提供 Java/Kotlin 编程接口 | Binder / JNI |
| 系统服务与原生库 | system_server、SurfaceFlinger、CameraService | 管理系统资源与硬件访问 | Binder / HIDL / AIDL |
| HAL 层 | Camera HAL、Audio HAL、Sensor HAL | 抽象硬件,提供统一接口 | HIDL / AIDL / .so |
| 内核与驱动层 | V4L2、ALSA、Input 子系统 | 直接操作硬件,提供设备节点 | 系统调用 / /dev |
五、常见误区与复盘
误区一:HAL 就是驱动。HAL 不是驱动,驱动运行在内核态,HAL 运行在用户态。HAL 负责“翻译”框架请求为驱动可识别的操作,二者职责不同。
误区二:所有 HAL 都必须独立进程。Treble 之前,很多 HAL 以动态库形式加载到系统服务进程中;Treble 之后,推荐使用 Binder 化 HAL,但并非强制所有 HAL 都独立进程。
误区三:框架层可以直接访问硬件。除极少数情况外,框架不应绕过 HAL 直接操作 /dev,否则会破坏可移植性与升级能力。
复盘要点:分析一个 Android 硬件问题时,先定位它发生在哪一层。若应用报错,先看框架 API;若系统服务异常,查 Binder 与 HAL 接口;若 HAL 返回失败,再查内核驱动与设备树。分层思维能显著缩小排查范围。