2. HIDL 与 AIDL 接口演进:从 HIDL 到 AIDL 的迁移背景与核心差异
在 Android 系统的演进过程中,Camera HAL 接口定义语言经历了从 HIDL(HAL Interface Definition Language)到 AIDL(Android Interface Definition Language)的重大迁移。这一变化并非简单的语法替换,而是 Android 系统架构对性能、稳定性与开发效率的深度优化。本节将系统梳理迁移背景,并对比两种接口语言的核心差异。
2.1 迁移背景:为什么从 HIDL 走向 AIDL?
HIDL 是 Android 8.0(Treble 项目)引入的接口定义语言,其核心目标是实现 Framework 与 HAL 的二进制兼容,从而加速系统升级。然而,随着 Android 系统的发展,HIDL 的局限性逐渐显现:
- 性能开销:HIDL 基于 Binder 的序列化机制较为笨重,高频 Camera 数据流场景下存在不必要的拷贝与延迟。
- 开发复杂度:HIDL 需要维护独立的
.hal文件、自动生成的 C++ 桩代码以及额外的types.hal类型定义,增加了开发与维护成本。 - 生态碎片化:HIDL 与 AIDL 两套接口体系并存,导致系统服务与 HAL 之间的交互方式不统一。
- Android 版本演进:从 Android 12 开始,Google 明确推动 "AIDL 化" 策略,逐步废弃 HIDL 接口,要求新开发的 HAL 模块优先使用 AIDL。
关键时间节点:
- Android 8.0:HIDL 随 Treble 项目首次引入。
- Android 12:官方推荐新 HAL 使用 AIDL,HIDL 进入维护模式。
- Android 14+:部分核心 HAL(如 Camera)的 AIDL 接口成为默认实现。
2.2 核心差异对比:HIDL vs AIDL
下表从多个维度对比 HIDL 与 AIDL 在 Camera HAL 场景下的关键差异:
| 对比维度 | HIDL | AIDL |
|---|---|---|
| 定义文件后缀 | .hal |
.aidl |
| 包名规范 | android.hardware.camera.provider@2.6 |
android.hardware.camera.provider |
| 接口继承 | 支持多继承(interface 继承) | 单继承(extends 方式) |
| 数据类型 | 独立类型系统(vec<T>、fmq_sync 等) |
复用 Java/C++ 原生类型 + Parcelable |
| 序列化机制 | 基于 Binder 的定制序列化 | 标准 Binder + Parcelable 序列化 |
| 同步/异步 | 默认同步,异步需显式定义 callback | 支持 oneway 关键字,更灵活的异步模型 |
| 版本管理 | 通过 @2.6 等版本号显式管理 |
通过接口继承 + 包名演进 |
| 代码生成 | 生成独立的 C++ 桩代码(BnHwCameraProvider 等) |
生成标准 Binder 桩代码(BnCameraProvider 等) |
| 性能开销 | 较高(额外类型转换与拷贝) | 较低(直接复用 Binder 原生机制) |
| 跨进程通信 | 支持 HwBinder(硬件 Binder) | 标准 Binder(与 Framework 统一) |
2.3 接口定义语法对比
以下通过 CameraProvider 的典型接口定义,直观展示 HIDL 与 AIDL 的语法差异:
HIDL 接口示例(CameraProvider@2.6)
// ICameraProvider.hal
package android.hardware.camera.provider@2.6;
interface ICameraProvider {
/**
* 获取 Camera 设备接口列表
*/
getCameraDeviceInterface_V3_x()
generates (Status status,
vec<string> cameraDeviceNames);
/**
* 设置回调
*/
setCallback(ICameraProviderCallback callback)
generates (Status status);
};
AIDL 接口示例(CameraProvider)
// ICameraProvider.aidl
package android.hardware.camera.provider;
interface ICameraProvider {
/**
* 获取 Camera 设备接口列表
*/
String[] getCameraDeviceInterface() throws CameraServiceException;
/**
* 设置回调
*/
void setCallback(in ICameraProviderCallback callback);
}
迁移要点:
- HIDL 的
generates关键字在 AIDL 中替换为方法返回值 +throws异常声明。 - HIDL 的
vec<T>在 AIDL 中直接使用原生数组T[]或List<T>。 - AIDL 支持
in、out、inout方向标记,更精确控制数据流向。
2.4 架构演进对比图
下图展示了从 HIDL 到 AIDL 的 Camera HAL 架构变化:
2.5 迁移路径与兼容性策略
对于现有的 Camera HAL 实现,从 HIDL 迁移到 AIDL 通常遵循以下步骤:
- 接口转换:将
.hal文件重写为.aidl文件,调整包名、方法签名与数据类型。 - 桩代码替换:移除 HIDL 生成的
BnHw*/BpHw*桩代码,替换为 AIDL 生成的Bn*/Bp*桩代码。 - 服务注册:将
hwservicemanager注册方式改为servicemanager标准 Binder 注册。 - 数据流适配:将 HIDL 特有的
fmq(快速消息队列)等机制替换为 AIDL 兼容的共享内存或标准 Binder 传输。 - 版本管理:移除 HIDL 的版本号后缀,通过 AIDL 接口继承实现版本演进。
兼容性注意事项:
- Android 12+ 系统同时支持 HIDL 与 AIDL 的 Camera HAL,但 新开发必须使用 AIDL。
- 迁移过程中,
ICameraProviderCallback等回调接口的oneway语义需要仔细验证,避免死锁。 - 部分 HIDL 特有的
@entry、@callflow注解在 AIDL 中没有直接对应,需通过接口设计保证调用顺序。
2.6 性能对比数据
在 Camera HAL 典型场景下,AIDL 相比 HIDL 的性能提升主要体现在以下方面:
| 性能指标 | HIDL | AIDL | 提升幅度 |
|---|---|---|---|
| 单次 Binder 调用延迟(μs) | ~120 | ~85 | ~29% |
| 大数据传输吞吐量(MB/s) | ~180 | ~240 | ~33% |
| 接口定义代码量(行) | ~350 | ~200 | ~43% |
| 编译时间(增量,秒) | ~8 | ~5 | ~37% |
总结:从 HIDL 到 AIDL 的迁移,本质上是 Android 系统对 HAL 接口层的 统一化与轻量化 改造。对于 Camera HAL 开发者而言,掌握 AIDL 接口定义与实现已成为必备技能,而理解 HIDL 的遗留代码则有助于维护旧版本系统的兼容性。