1. 课程导入

在 Android 系统开发中,Service 是一个被频繁提及却容易被混淆的概念。应用开发者熟悉的 Service 是四大组件之一,运行在应用进程内,由 ActivityManagerService 调度;而系统开发者口中的 Native Service,则是运行在 system_server 之外、以 C/C++ 编写、通过 Binder 驱动直接向内核注册节点的系统级服务。本课程讨论的是后者——它是 Android 系统能力的“地基”,负责音频、相机、显示、传感器、电源、存储等几乎所有硬件相关能力的对外暴露。

一句话定义:Android Native Service 是运行在独立 Native 进程(或 system_server 的 native 线程)中,使用 C/C++ 实现,通过 Binder 机制向 Java 层或其他 Native 进程提供跨进程接口的系统服务。它通常由 init 进程根据 .rc 脚本拉起,以 service 关键字声明,并注册到 ServiceManager 中供全局查询。

一、从 Java Service 到 Native Service:为什么需要两套体系

Android 早期(1.0~2.x)大量系统能力直接以 Java Service 形式实现在 frameworks/base/services/java 中,例如早期的 ActivityManagerService、WindowManagerService。但随着硬件抽象层(HAL)和多媒体、图形栈的复杂化,Java 层暴露出三个难以回避的问题:

  • 性能与实时性:音频混音、相机帧回调、传感器采样对延迟敏感,JVM 的 GC 停顿和 JNI 边界开销不可接受。
  • 复用既有 C/C++ 库:Stagefright、Skia、libhardware、Vulkan 等本身就是 Native 库,用 Java 重写成本极高。
  • 进程隔离与稳定性:把相机、音频等易崩溃模块放进独立 Native 进程,可避免拖垮 system_server。

于是从 Android 4.x 开始,Google 逐步将 MediaPlayerService、CameraService、AudioFlinger、SurfaceFlinger、SensorService 等迁移为 Native Service,形成“Java Service 管策略、Native Service 管执行”的分层格局。到 Android 8.0 引入 Treble 与 HIDL,Android 10 引入 AIDL HAL,Native Service 的边界进一步下沉到 vendor 分区,成为连接 framework 与 HAL 的关键枢纽。

二、Java Service 与 Native Service 的核心差异

理解两者差异,是后续所有调试与开发工作的前提。下表从语言、进程、注册方式、接口描述、生命周期等维度做对照:

对比维度Java ServiceNative Service
实现语言Java / KotlinC / C++
运行位置system_server 或应用进程独立 Native 进程(如 audioserver、cameraserver)
启动方式SystemServer 中 addServiceinit 解析 .rc 脚本 fork/exec
注册中心ServiceManager(Java 代理)ServiceManager(Binder 驱动 /dev/binder)
接口描述AIDL(.aidl 文件)AIDL(NDK backend)或 HIDL
典型代表ActivityManagerService、PackageManagerServiceAudioFlinger、CameraService、SurfaceFlinger
调试手段dumpsys、am、logcatdumpsys、binder 节点、strace、perfetto

需要特别强调的是:两者并非替代关系,而是协作关系。例如应用调用 AudioManager,实际链路是 AudioManager(Java) → AudioService(Java, system_server) → AudioFlinger(Native) → Audio HAL。Java 层负责权限、策略与状态机,Native 层负责数据通路与硬件交互。

三、整体知识框架与学习路径

本课程围绕“能看懂、能调试、能新增、能优化”四个目标展开,知识框架可归纳为五层:

  1. 基础层:Binder 驱动、ServiceManager、IPCThreadState、Parcel 序列化。
  2. 框架层:BnInterface/BpInterface、AIDL NDK 生成规则、defaultServiceManager() 与 addService。
  3. 启动层:init.rc 语法、service/on 段、SELinux 域与 service_contexts。
  4. 实现层:典型服务剖析(AudioFlinger、CameraService、SensorService)与 HAL 对接。
  5. 工程层:Android.bp 编译、dumpsys 调试、binder 泄漏排查、性能与稳定性优化。

下图给出 Native Service 在 Android 系统中的位置与一次跨进程调用的完整信号链,帮助建立全局视角:

Android Native Service 位置与跨进程调用信号链 应用进程 (App Process) AudioManager CameraManager SensorManager Binder Proxy (BpInterface) system_server 进程 (Java Service 层) AudioService CameraServiceProxy SensorManagerService 策略 / 权限 / 状态机 Binder 驱动 (/dev/binder) — 内核态 ServiceManager 注册表 · 引用计数 · 线程池调度 · 一次拷贝 mmap Native Service 进程 (C/C++) AudioFlinger audioserver CameraService cameraserver SensorService sensorservice BnInterface 实现 onTransact 分发 HAL / 内核驱动 (Vendor 分区) AIDL HAL · HIDL · ALSA · V4L2 · IIO · DRM/KMS ① 调用 ② 转发 ③ 跨进程 ④ 访问硬件

四、典型场景:一次录音请求的完整链路

以应用调用 AudioRecord 录音为例,可清晰看到 Java 与 Native 的分工:

App: AudioRecord.startRecording()
  → AudioRecord (JNI) → android_media_AudioRecord_start
  → AudioSystem::startInput (Native)
  → BpAudioFlinger → Binder 驱动 → BnAudioFlinger::onTransact
  → AudioFlinger::startInput → AudioStreamIn::start
  → Audio HAL (AIDL) → ALSA / 驱动

这条链路中,AudioService 负责判断录音权限、焦点与并发策略;AudioFlinger 负责创建输入流、混音与缓冲区管理;HAL 负责真正打开 PCM 设备。任何一环出错,都会在 dumpsys media.audio_flinger 或 logcat -b all 中留下痕迹。

学习建议:不要一上来就啃 Binder 驱动源码。建议先跑通一个最小 Native Service(HelloService),用 service list | grep hello 验证注册成功,再逐步加入 AIDL 接口、SELinux 策略与 dumpsys 输出。有了可运行的“活体”,再回头看 Binder 原理会事半功倍。

五、常见误区与复盘

  • 误区一:把 Native Service 等同于 HAL。HAL 是硬件抽象接口,Native Service 是系统服务实现,二者是调用方与被调用方的关系,一个 Native Service 可对接多个 HAL。
  • 误区二:认为 Native Service 一定在独立进程。部分服务(如 SurfaceFlinger 的某些线程)可运行在 system_server 的 native 线程中,判断依据是 ps -A 与 dumpsys -l 的实际输出。
  • 误区三:忽略 SELinux。服务注册成功但调用失败,十有八九是 avc: denied,需检查 service_contexts 与 te 规则。
  • 误区四:只改代码不验证。每次修改后应执行 adb shell dumpsys <service> 与 adb shell service list,确认服务存活与接口可见。