1. 课程导入

在Android系统中,应用进程与系统服务之间并不是直接调用,而是通过Binder驱动完成跨进程通信。每一个系统服务在启动后,都需要把自己的Binder句柄注册到ServiceManager中,客户端才能通过名称查询到它并建立连接。可以说,ServiceManager是Android服务体系的“电话总机”,而服务启动过程则是把各个系统能力接入这台总机的关键动作。本课程围绕“服务如何启动、如何注册、如何被查询、如何被使用”这条主线展开,帮助学习者建立从内核Binder到Framework层ServiceManager的完整工程认知。

本课程的核心目标不是背诵API,而是理解一条完整的服务生命周期链路:进程启动 → 服务实例创建 → Binder对象准备 → 向ServiceManager注册 → 客户端查询 → 跨进程调用 → 服务退出与注销。掌握这条链路后,分析系统服务异常、定制系统服务、排查Binder通信问题都会变得有章可循。

一、核心概念:先建立四个关键角色

理解Android服务启动,首先要区分四个角色。第一是Binder驱动,它位于内核空间,负责进程间数据传递和句柄管理;第二是ServiceManager,它是系统启动最早的服务之一,负责维护“服务名称 → Binder引用”的映射表;第三是系统服务进程,例如system_server,它承载了大量Framework层服务;第四是客户端进程,它通过ServiceManager查询目标服务,拿到代理对象后发起调用。

这四个角色之间的关系可以用下面的结构图表示。图中同时标出了服务注册与服务查询两条方向相反的路径,便于理解ServiceManager作为中间枢纽的位置。

Android服务启动与ServiceManager核心结构 内核空间 Binder 驱动 负责跨进程数据传递与Binder句柄管理 ServiceManager 服务名称 → Binder引用 映射表 系统服务进程 system_server / 自定义服务 addService("name", binder) 客户端进程 getService("name") 获得代理对象并调用 注册服务 查询服务 通过Binder驱动通信

二、整体知识框架:从启动到调用的五层结构

本课程的知识框架可以划分为五层。第一层是Binder基础层,包括Binder驱动、Binder协议、Parcel序列化;第二层是ServiceManager层,包括服务注册、查询、权限校验和死亡通知;第三层是服务启动层,包括init进程解析rc文件、启动system_server、ServiceManager启动顺序;第四层是Framework服务层,包括SystemServiceManager、ServiceThread、BinderService等机制;第五层是工程实践层,包括自定义系统服务、SELinux策略配置、服务调试与排障。

层次 核心对象 关键动作 常见问题
Binder基础层 Binder驱动、Parcel 打开设备、内存映射、数据收发 句柄泄漏、传输大小超限
ServiceManager层 ServiceManager、ServiceMap addService、getService、listServices 服务未注册、名称冲突
服务启动层 init、rc脚本、system_server 解析配置、fork进程、启动服务 启动顺序错误、权限不足
Framework服务层 SystemServiceManager、BinderService onStart、publishBinderService 服务启动超时、线程阻塞
工程实践层 自定义服务、SELinux策略 注册服务、配置te文件、调试 avc denied、客户端拿不到服务

三、实战路线图:按工程顺序推进

学习本课程建议按照“先看启动顺序,再看注册机制,最后做自定义服务”的路线推进。具体可以分为六个阶段:

  1. 阶段一:观察启动日志。通过logcat和dmesg观察ServiceManager、system_server的启动顺序,确认服务注册的时间点。
  2. 阶段二:理解Binder注册。阅读addService和getService的调用链,理解Binder驱动如何维护句柄。
  3. 阶段三:分析system_server。查看SystemServer.java中startBootstrapServices、startCoreServices、startOtherServices的启动分组。
  4. 阶段四:编写自定义服务。实现一个继承Binder的本地服务,并通过ServiceManager注册。
  5. 阶段五:配置SELinux。为自定义服务添加type、allow规则和service_contexts配置。
  6. 阶段六:调试与验证。使用service list、dumpsys、logcat验证服务是否注册成功并可被调用。
# 查看当前已注册的系统服务
adb shell service list | head -n 20

# 查看某个服务的详细信息
adb shell dumpsys activity services

# 观察ServiceManager相关日志
adb logcat -s ServiceManager:V SystemServer:I

# 查看SELinux拒绝日志
adb shell dmesg | grep avc

四、典型场景与常见误区

在实际工程中,最常见的场景是“自定义系统服务启动后,客户端调用时报ServiceNotFound”。这类问题通常不是服务代码本身错误,而是注册时机、SELinux策略或服务名称不一致导致的。另一个高频场景是服务启动阻塞,例如在onStart中执行耗时操作,导致system_server启动超时,进而引发系统重启。

常见误区一:认为ServiceManager只是一个普通Java类。实际上它是native服务,运行在独立的servicemanager进程中,通过Binder驱动与system_server通信。
常见误区二:只关注Java层addService,忽略SELinux和init.rc配置。很多“服务注册失败”最终都定位到权限或启动顺序问题。
常见误区三:在服务启动阶段执行阻塞操作。系统服务启动有严格的时间窗口,阻塞会导致Watchdog触发。
建议在学习过程中始终维护一张“服务注册检查清单”:服务名称是否唯一、Binder对象是否已准备、addService是否在正确线程调用、SELinux是否放行、客户端是否有权限查询。按清单逐项排查,可以显著缩短排障时间。

本课程后续将围绕这条主线逐步展开:从Binder驱动的基本原理,到ServiceManager的注册与查询实现,再到system_server的启动流程,最终完成一个可运行的自定义系统服务。掌握这些内容后,你不仅能够读懂Android系统服务的启动日志,还能独立完成系统服务的定制、注册、权限配置与调试。