写 Linux 驱动时,我们习惯沿着"用户程序 → 系统调用 → 驱动 → 硬件"理解一次操作。进入 Android 后,又遇到了 Manager、System Service、JNI、Binder、HAL、ART。它们到底是什么关系?
要把这张地图看懂,先对每个模块问三个问题:它负责什么?它运行在哪个进程?它通过什么接口与下一个模块通信?
本文以现代 AOSP 架构为主,兼顾传统 HAL、HIDL 和 AIDL 的演进。图均为依据官方资料重绘的教学示意,省略非关键内部类和线程,并非某款手机的完整实测拓扑。资料核查日期:2026-10-19。源码示例使用可访问的 AOSP 主线链接,主线会变化,不能直接等同于你的 Android 发布版本或厂商 BSP。
一、先把 Android 的分层地图展开

先看主干:应用使用 Framework 暴露的能力;需要统一管理的操作交给系统服务;涉及某类硬件时,服务可能经 HAL 调用厂商实现,再进入内核驱动。旁边的 ART 和原生库支撑这些代码运行,不能把所有模块画成请求必经的串行站点 。AOSP 架构总览
App:表达"我要做什么"
App 实现业务、界面和交互,例如拍照、播放声音、请求振动。系统预装应用也属于应用,但可能拥有普通第三方应用没有的系统 API 访问资格或特权权限。不能把"预装"直接理解成"可以任意操作驱动"。Android API 与系统 API 的区分
Framework:把系统能力组织成可用的 API
Framework 包含供应用使用的类、接口和实现,例如 CameraManager、Vibrator、View、资源管理等。你在 App 里调用一个 Manager,其客户端对象通常也在 App 进程里;它可能在本地处理请求,也可能通过 IPC 访问服务端。
因此,日常说"改 Framework"时,必须继续问:改的是 App 侧 API/客户端、系统服务端,还是 native 支撑代码 ?把 Framework 理解成一个独立进程,会从这里开始看错调用链。Framework 的进程归属
System Services:统一管理资源、权限和策略
系统服务负责应用之间无法各自为政的事情,例如窗口、应用生命周期、硬件使用仲裁。它们可能检查调用者身份与权限、管理共享资源、实施系统策略,再调用其他组件。
system_server 承载许多 Java 系统服务,但它不是所有服务的总容器。相机的 CameraService 在 cameraserver 进程中;负责显示合成的 SurfaceFlinger 也是独立的原生服务。"系统服务"是一类职责,"system_server"是一个进程。 Binder 的相机调用示例、cameraserver 主程序
Native Libraries 与 ART:一个提供原生能力,一个支撑托管代码执行
Native 即原生代码,常见为 C/C++。Bionic 提供 Android 的 C 库能力,libbinder 提供 Binder 的用户态支撑;原生库可以被不同进程加载,原生守护进程则自身就是进程。它们中的一些可以直接访问内核接口,不依赖某个硬件 HAL。原生库与守护进程
ART 是 Android 的运行时,负责 DEX 代码执行、垃圾回收等;AOT/JIT 是其相关执行技术。ART 支撑 App 和其他托管代码运行,不能把它画成"Framework 调完之后,还要把请求交给一个 ART 服务再往下传"。Android Runtime、平台架构
HAL:定义 Android 认识的硬件能力
HAL 是 Hardware Abstraction Layer,硬件抽象层。它由标准接口及相应实现共同构成:上层按照约定请求能力,厂商在用户态把这些能力接到设备实现上。
例如,相机 HAL 描述设备、流配置、拍摄请求和结果等相机语义;下层如何协调 sensor、ISP、算法库和驱动,则有很大的平台差异。HAL 实现不是只有一行 ioctl(),也不是内核驱动的另一个名字。HAL 总览、Camera HAL
Kernel / Driver:提供内核机制并控制设备
Linux 内核负责进程调度、内存、文件系统、网络和设备驱动等。驱动把用户态可用的内核接口接到具体硬件机制上。Android 使用基于 Linux LTS 的内核,并包含 Android 相关修改;现代 GKI 架构还区分通用内核与厂商模块。
对 Linux 开发者而言,你熟悉的驱动知识依然有效;需要补上的主要是驱动接口之上,Android 如何组织服务、策略和硬件语义 。Android 内核总览
二、把"分层图"换成"进程图"

图中有三个用户态进程:App、cameraserver、厂商 Camera HAL 服务。一次相机控制操作可以跨过两次进程边界,最后由厂商栈访问设备相关内核接口。图里的 Binder 横向箭头是简写:真正的 IPC 传递仍经过内核 Binder 驱动。
这里有两个容易混淆的名字:CameraManager 是 App 侧的入口;CameraService 是服务端实现。调用前者不意味着代码已经进入后者的进程。官方 Camera 架构、CameraManager 源码
同理,应用四大组件之一的 android.app.Service,也不等同于平台系统服务;应用 Service 是否独立进程,要看应用配置。Binder 也不是只给系统服务使用,应用之间同样可以用它通信。AIDL 开发指南
三、跨层调用到底靠什么?看清四种箭头

1. 普通方法调用:代码分层了,进程未必变
App 调用 Framework 客户端方法,可以只是同一进程中的一次方法调用。类名带 Manager,不意味着这一步必然发生 IPC;具体要看方法实现。
2. JNI:跨语言边界
JNI 连接 Java/Kotlin 所使用的托管世界与 C/C++ 原生代码。JNI 本身不负责把请求送到另一个进程 。比如系统服务的 Java 代码经 JNI 调用该进程内的 C++ 实现,进程仍是原来的进程;这段 C++ 代码后续还可以发起 Binder IPC 或系统调用。JNI 官方说明
3. Binder:跨进程边界
远程调用时,客户端 Proxy 编组参数并发起事务,内核 Binder 驱动把事务送到目标进程,由服务端 Stub/分发代码解组并调用实现。同步调用还会把回复送回客户端;异步 oneway 等情形另有语义,不能把每次事务都理解成同步往返。
AIDL 是接口定义语言及其生成工具链的一部分;它生成接口与通信代码,不是 Binder 内核驱动本身 。AIDL 接口对象如果就在同一进程,本地调用可以直接执行,不必发生一次真正的远程事务。Binder 总览、AIDL 调用规则
ServiceManager 负责 Binder 服务的注册与查找。客户端拿到服务引用以后,业务调用通过 Binder 到目标服务,不是每个请求都先由 ServiceManager 代理转发。CameraManager 的服务获取与调用实现
4. 系统调用:跨用户态与内核态边界
用户态代码通过系统调用使用内核能力,例如读写文件、操作 socket 或访问设备。HAL 可以经原生库调用 read()、write()、ioctl() 等接口,但具体使用哪个接口取决于子系统和 BSP。HAL 不会以普通 C 函数调用的方式,直接跳进内核驱动的某个函数。
Binder 自身也依赖内核接口:它和"用户态/内核态边界"并不互斥。图中把它单列,是为了区分"跨进程调用服务"和"访问目标设备"这两个目的。Binder 事务经过内核的过程
为什么普通 App 通常不能直接操作硬件设备节点?
服务链同时承担访问控制。App 能使用 Java 或 JNI,并不意味着它能越过应用沙箱:native 代码同样受 Linux UID/GID、文件权限和 SELinux 等机制约束;系统 API 的权限检查与底层设备访问权限也不是一回事。SELinux 约束还覆盖系统服务与 HAL 进程。换成 C/C++,不会自动获得驱动访问权。 应用沙箱、Android SELinux
四、用一次振动请求,把整条链串起来

先限定场景:这里主要展开单个系统振动器的执行支路,选取 AIDL HAL 分支;不展开 HAL 管理器、多振动器同步控制、外接输入设备振动、音频耦合触觉以及全部效果调度细节。
HAL 层还存在 android.hardware.vibrator.IVibratorManager,用于获取各振动器的 IVibrator 接口,并在相应能力受支持时进行多振动器同步控制。它与 App 访问系统服务时使用的 android.os.IVibratorManagerService 是不同层的接口。图中省略管理支路,不表示每次振动都必须依次调用这两个 HAL 接口。HAL 管理器接口
- App 表达意图。 调用
Vibrator.vibrate(...),提交一个振动效果。 - 客户端组织请求。
SystemVibrator将效果交给VibratorManager,SystemVibratorManager通过IVibratorManagerService访问服务端。这些客户端代码仍在 App 进程内。SystemVibrator、SystemVibratorManager - 系统服务作出决策。
VibratorManagerService接收请求,处理权限、状态和策略等,再安排效果执行。这个服务不是纯粹的透明转发器,请求可能被忽略或取消。VibratorManagerService - 服务内部进入原生实现。 调度过程中使用
VibratorController,其NativeWrapper经 JNI 接入 C++ HAL 适配代码。比如定时开启分支可进入 nativevibratorOn();预置效果、组合效果等有各自入口,不是所有效果最终都等价于一次on()。VibratorController、对应 JNI 实现 - 厂商 HAL 执行硬件语义。 AIDL Vibrator HAL 提供约定的接口,厂商实现再使用该平台的内核接口控制振动相关硬件。接口、能力与实现方式需要一起看,不能凭空指定一个所有手机通用的
/dev/...或 sysfs 路径。AIDL HAL 与 Vibrator 服务实例示例
沿着图回看,App 与系统服务之间用 Binder;服务内部的 Java/C++ 连接用 JNI;服务与独立 HAL 进程之间再次使用 Binder;HAL 访问驱动则跨越用户态与内核态。这些边界可以出现在同一条功能链里,但不是同一件事。
五、相机预览:控制流与数据流不能画成一条线

Camera2 是应用 API 的名称,Camera HAL3 是相机 HAL 的操作模型,HIDL/AIDL 则用于定义和承载接口;这三个维度不能互相替代,Camera2 也不等于"HAL2"。Camera HAL 的模型与接口演进
控制流:告诉系统"打开谁、配置什么、拍哪一帧"
Camera2 通过 Binder 接口访问 CameraService。打开设备时涉及 ICameraService.connectDevice();打开后,设备操作使用 ICameraDeviceUser 等接口。CameraManager、CameraDevice、CameraCaptureSession 是不同职责的 API,不能认为一个 openCamera() 就完成了持续预览的全部工作。Camera 架构、CameraManager 实现
HAL 一侧又区分 Provider、Device、Session 等接口:Provider 侧重枚举、状态与设备接口获取;实际会话管理与请求处理涉及 Device/Session。这些是接口角色,不必分别对应三个进程,也不是每帧都依次穿过三个独立服务。 Camera HAL
数据流:把图像 buffer 交给指定消费者
拍摄请求会产生结果元数据及输出图像。元数据和状态通过相应回调返回;HAL 与底层相机流水线协作,将像素写入面向输出 Surface 的 buffer。与此同时,cameraserver 中的相机框架负责输出流的缓冲区管理:Camera3OutputStream 参与 buffer 的获取、向 HAL 交付,以及完成后的入队和同步处理。启用 HAL3 buffer management API 时,HAL 可以按需向相机框架请求 buffer,再通过规定的接口归还。不能把"填充像素"和"管理输出 buffer 的交付、入队"都理解成 HAL 直接完成;这些管理操作也不意味着在 cameraserver 复制一份像素。 Camera3OutputStream 实现、HAL3 缓冲区管理契约
BufferQueue 连接图形缓冲区的生产者与消费者,双方通过获取、提交、获取使用和归还等动作复用缓冲区。队列传递的是 buffer 的引用/句柄及相关信息,BufferQueue 本身不复制像素 ;但厂商算法、格式转换和 App 处理仍可能发生复制,所以不能据此保证整条相机流水线"绝对零拷贝"。BufferQueue 与 Gralloc
图中选择当前 AOSP 的 SurfaceView / BLAST 预览分支 :输出 Surface 对应的 BufferQueue 先由 App 进程内的 BLAST 消费端 获取 buffer,再通过 SurfaceControl.Transaction 将 buffer、fence 等提交给 SurfaceFlinger。SurfaceFlinger 在这里是接收事务并组织显示合成的组件,不能直接画成这个 BufferQueue 的消费端。BLAST 位于 App 进程,不代表像素必须复制到 Java。SurfaceView 创建 BLASTBufferQueue、BLAST 获取 buffer 并构造事务
SurfaceFlinger 随后与用户态 HWC HAL 协作,经显示驱动和硬件呈现;GPU 可以参与 SurfaceFlinger 的客户端合成。使用 TextureView、ImageReader 或编码器时,消费者及后续路径会不同。不是所有相机输出都先经过 SurfaceFlinger。 图形生产者与消费者、SurfaceFlinger 与 WindowManager
最后一个面向 BSP 开发者的提醒:不能把所有 Android 相机的底层都写成 V4L2。官方外接 USB Camera 方案使用 UVC/V4L 路径,但这不足以概括厂商内置相机、ISP 及算法栈。外接 USB 相机官方方案
六、反方向看一次:触摸事件怎样向上传递?

前面是 App 发起请求,现在看硬件主动产生事件。触摸控制器把事件交给 Linux 输入驱动,驱动输出标准 Linux input 事件;EventHub 读取 evdev,InputReader 做设备解析和事件映射;InputDispatcher 再根据窗口、焦点等状态,把事件送到对应 App。官方输入管线说明
应用接收事件的 InputChannel 使用基于 socket 的输入传输机制,不能把它画成每个触摸事件都执行一次普通 Binder RPC。Binder 仍可参与输入系统的接口交互,但不是这条事件数据传输链的全部。InputTransport 源码
这条链也说明:不是每种硬件操作都需要一个独立的、类似 Camera HAL 的服务。 传统触摸/按键输入可以通过标准 evdev 接入 Android 输入系统。这里不是说输入子系统不存在任何 HAL 扩展,而是不要往具体事件链中添加实际不存在的站点。
七、HAL 的历史版本,为什么经常把人看晕?

读资料时看到传统 .h、HIDL 的 .hal、AIDL 的 .aidl,很可能是在看不同年代、不同接口的实现。
| 阶段 | 重点 | 阅读时注意 |
|---|---|---|
| 较早的传统 HAL | 共享库、C 接口与函数表等实现模式 | 不要把历史模块加载方式直接当成所有现代 HAL 的工作方式 |
| Android 8 / Treble 时代 | HIDL 用于明确 Framework 与厂商实现之间的接口边界 | 常见 Binderized HAL,也存在 passthrough / Same-Process HAL 等例外 |
| Android 11 起 | 开始支持 AIDL HAL | AIDL 早已用于其他场景,不能写成 Android 11 才发明 AIDL |
| 当前开发方向 | 新 HAL 开发按接口规范采用 AIDL;已有 HIDL 实现仍可能存在 | 支持范围受具体接口、目标版本及兼容性要求约束 |
以上依据 HAL 总览、AIDL for HALs。Camera HAL 的 AIDL 支持从 Android 13 引入,不能把"AIDL HAL 总体可用的时间"与"某类 HAL 迁移的时间"混为一谈。Camera HAL 版本说明
还有一个资料校对细节:官方 HAL 总览写 Android 13 起 HIDL 弃用,而 HIDL 专页写 Android 10 起弃用,两页时间表并不一致。本文不据此推断一个统一的"所有 HAL 停用日期";能确定的是:新开发推荐 AIDL,弃用也不等于已有 HIDL HAL 立即全部移除。
跨 system/vendor 的 AIDL HAL 还要求 Stable AIDL 与 VINTF 配套,不能只写一个 .aidl 文件就认为具备长期兼容性。VINTF 用 manifest 描述所提供的接口,用 compatibility matrix 描述要求,二者需要匹配。AIDL HAL 稳定性要求、VINTF
图中下方还区分了另一条边界:HAL 接口连接 Android 系统侧与厂商侧;GKI 的 KMI 连接通用内核与厂商内核模块。 两者的对象不同,不能因为都提到"稳定接口",就把 HAL 与内核模块混成一层。GKI 与 KMI
八、知道分层后,怎样回到代码里定位?
下面是阅读入口,不是"一个目录严格对应一个层"的完整清单。路径均相对于相应 AOSP 仓库;厂商 BSP 的额外实现需要在厂商源码中确认。
| 想找什么 | 已核对的入口 | 先问什么 |
|---|---|---|
| App 侧振动客户端 | frameworks/base/core/java/android/os/SystemVibrator.java、SystemVibratorManager.java |
请求是否仍在本地?哪一行开始访问远端接口? |
| 振动系统服务与控制器 | frameworks/base/services/core/java/com/android/server/vibrator/ |
请求是否被策略拦截?效果由谁调度? |
| 振动 Java/native 连接 | frameworks/base/services/core/jni/com_android_server_vibrator_VibratorController.cpp |
Java native 方法注册到哪个 C++ 函数? |
| 相机 App 侧入口 | frameworks/base/core/java/android/hardware/camera2/CameraManager.java |
打开设备和提交请求分别用哪个 Binder 接口? |
| 相机服务宿主 | frameworks/av/camera/cameraserver/main_cameraserver.cpp |
服务到底运行在哪个进程? |
| AOSP 硬件接口定义 | hardware/interfaces/ |
这是接口定义、示例实现,还是设备实际加载的厂商实现? |
| Android 公共内核 | kernel/common 仓库 |
当前设备使用哪条内核分支?驱动是否是额外厂商模块? |
这些入口对应前文源码链接;HAL 目录约定见 AIDL HAL 接口位置,公共内核仓库见 Kernel overview。AOSP 的接口或默认实现不能直接证明某个量产设备使用了哪套厂商代码。
调试时,可以把问题拆成四段:请求有没有到服务?服务有没有允许并向下执行?HAL 有没有正确完成适配?驱动和硬件有没有产生预期行为? 相机等高带宽场景再单独检查 buffer、消费者与同步。不要仅凭"API 没抛异常",就把整条链判定成功;也不要仅凭"驱动单测正常",就断言上层权限、策略和格式协商一定没问题。这是依据上述调用边界得到的排查方法,并非对任何具体设备的诊断结论。
阅读一个新子系统时,可以在纸上留三列:职责层 / 运行进程 / 下一跳机制。每查到一个真实类、接口或驱动,就把它填进去;你得到的会是一张能继续追源码、查日志的图,而不只是几层颜色不同的方框。
官方参考资料
正文中的链接紧邻其支持的内容,下面保留主要索引,方便继续阅读。