ServiceManager
ServiceManager 是 Android 系统中 Binder 通信的 “服务注册表”,负责管理所有系统服务(如 AMS、WMS)的 Binder 引用,为进程间通信(IPC)提供 “服务查询与注册” 的核心能力。所有进程(包括 App 进程、SystemServer 进程)都需通过 ServiceManager 找到目标服务的 Binder 代理,才能发起跨进程调用。
ServiceManager 的核心定位与作用
在 Android 的 Binder 通信模型中,进程间无法直接找到对方的 Binder 实例,必须通过一个 “中间枢纽” 来匹配 “服务提供者” 和 “服务使用者”—— 这个枢纽就是 ServiceManager。其核心作用可概括为 “两个核心动作”:
- 服务注册(addService):系统服务(如 AMS)启动后,将自身的 Binder 实例注册到 ServiceManager,并关联一个唯一的 “服务名称”(如 AMS 对应
"activity")。 - 服务查询(getService):其他进程(如 App 进程)需要调用系统服务时,通过 “服务名称” 向 ServiceManager 查询,获取该服务的 Binder 代理(Proxy),再通过代理发起跨进程调用。
简单说:ServiceManager 就像 “通讯录”—— 系统服务启动时 “登记姓名和联系方式(Binder)”,其他进程通过 “姓名(服务名称)” 查 “联系方式(Binder 代理)”,最终实现跨进程沟通。
ServiceManager 的启动流程(早于 SystemServer)
ServiceManager 是 Native 层进程(非 Java 进程),启动时机非常早,甚至早于 Zygote 和 SystemServer,是系统 Binder 通信的 “基础设施”。其启动流程依赖 init 进程,分为 3 个关键步骤:
阶段 1:由 init 进程触发启动(系统初始化早期)
Android 系统开机后,init 进程(Linux 内核启动的第一个用户态进程)会解析 /init.rc 配置文件,其中明确定义了 ServiceManager 的启动规则:
# /init.rc 中 ServiceManager 的启动配置
service servicemanager /system/bin/servicemanager
class core
user system
group system readproc
critical # 标记为“关键进程”,崩溃会导致系统重启
onrestart restart healthd
onrestart restart zygote # ServiceManager 重启时,需同步重启 Zygote(依赖其通信)
onrestart restart media
onrestart restart surfaceflinger
socket service_manager seqpacket 666 system system # 创建 Binder 通信的 socket
init进程根据配置,执行/system/bin/servicemanager可执行文件,启动 ServiceManager 进程。- 关键参数
socket service_manager ...:创建一个名为service_manager的 UNIX 域套接字,作为 ServiceManager 与其他进程通信的 “通道”(所有注册 / 查询请求都通过该 socket 传输)。
阶段 2:初始化 Binder 驱动与通信环境
ServiceManager 进程启动后,会执行 Native 层代码(C/C++ 实现,源码位于 frameworks/native/cmds/servicemanager/),核心初始化逻辑如下:
打开 Binder 驱动:调用
open("/dev/binder", O_RDWR)打开 Linux 内核的 Binder 驱动设备文件(/dev/binder是 Binder 通信的内核层入口),获取 Binder 设备描述符。注册为 “上下文管理者”(Context Manager):调用
ioctl(fd, BINDER_SET_CONTEXT_MGR, 0)向 Binder 驱动注册,声明自己是 “服务上下文管理者”—— 这是 ServiceManager 的专属身份,其他进程无法抢占。此步骤的核心作用:让 Binder 驱动知道 “所有服务注册 / 查询请求,都要转发给 ServiceManager 处理”。
初始化 socket 监听:绑定并监听之前
init进程创建的service_managersocket,等待接收其他进程的服务注册 / 查询请求。
阶段 3:进入循环监听(处理请求)
初始化完成后,ServiceManager 会进入 永久循环,通过 epoll(IO 多路复用机制)监听 socket 上的请求,核心逻辑是 “接收请求 → 解析请求 → 处理请求 → 返回结果”:
- 接收请求:通过 socket 接收来自其他进程(如 SystemServer、App 进程)的请求数据(如 “注册 AMS 服务”“查询 WMS 服务”)。
- 解析请求:解析请求类型(是
addService还是getService)、服务名称、Binder 引用等信息。 - 处理请求:
- 若为
addService:将 “服务名称 → Binder 实例” 的映射关系存入内部哈希表(svcinfo_list),完成服务注册。 - 若为
getService:从哈希表中根据 “服务名称” 查找对应的 Binder 实例,生成 Binder 代理(Proxy),返回给请求进程。
- 若为
- 返回结果:通过 socket 将处理结果(如 Binder 代理、注册成功 / 失败标识)回传给请求进程。
ServiceManager 会一直运行在循环中,直到系统关机,是系统 Binder 通信的 “永久枢纽”。
ServiceManager 的核心数据结构与接口
ServiceManager 内部通过简单的数据结构和接口实现服务管理,核心如下:
1. 核心数据结构:服务哈希表(svcinfo_list)
ServiceManager 用一个链表结构(struct svcinfo)存储已注册的服务,每个节点包含 3 个关键信息:
name:服务名称(字符串,如"activity"对应 AMS,"window"对应 WMS)。handle:服务的 Binder 句柄(由 Binder 驱动分配的整数标识,唯一对应一个 Binder 实例)。next:下一个服务节点的指针,形成链表。
本质是 “服务名称 → Binder 句柄” 的映射,便于快速查询。
2. 核心接口(对外提供的 3 个关键能力)
ServiceManager 通过 Binder 驱动和 socket 对外暴露 3 个核心接口,所有进程都通过这些接口与它交互:
| 接口名 | 作用 | 调用方 | 关键参数 |
|---|---|---|---|
addService | 将系统服务的 Binder 实例注册到 ServiceManager | SystemServer 进程 | 服务名称(如 "activity")、Binder 句柄、权限标识 |
getService | 根据服务名称查询对应的 Binder 代理(Proxy) | App 进程、其他系统进程 | 服务名称(如 "window") |
listServices | 查询当前已注册的所有系统服务名称(用于调试或系统工具) | 调试工具、系统进程 | 无(或权限参数) |
示例:App 进程调用 startActivity() 时,底层逻辑是:
- App 进程通过
getService("activity")向 ServiceManager 查询 AMS 的 Binder 代理。 - ServiceManager 从哈希表中找到
"activity"对应的 Binder 句柄,生成代理返回给 App 进程。 - App 进程通过 AMS 代理,向 SystemServer 中的 AMS 发起跨进程调用,完成 Activity 启动。
ServiceManager 与其他核心组件的关系
ServiceManager 是 Android 系统 IPC 通信的 “中枢”,与 Zygote、SystemServer、App 进程的交互紧密:
| 组件 | 与 ServiceManager 的交互方式 |
|---|---|
| init 进程 | 启动 ServiceManager 进程,创建通信 socket;ServiceManager 崩溃时,init 会重启它(因标记为 critical)。 |
| SystemServer 进程 | 系统服务(如 AMS、WMS)启动后,通过 addService 注册到 ServiceManager;依赖 ServiceManager 提供的服务查询能力(如 AMS 查询 PMS)。 |
| App 进程 | 通过 getService 查询系统服务的 Binder 代理,实现跨进程调用(如调用 AMS 启动 Activity、调用 WMS 显示窗口)。 |
| Binder 驱动 | 为 ServiceManager 分配 “上下文管理者” 身份;为注册的服务分配 Binder 句柄;转发 ServiceManager 与其他进程的请求 / 响应。 |
ServiceManager 的关键特性
- Native 层实现:ServiceManager 是纯 Native 进程(C/C++ 编写),不依赖 Java 虚拟机,启动速度快,可在系统早期提供服务(早于 Zygote 和 SystemServer)。
- 关键进程属性:在
init.rc中标记为critical(关键进程),若崩溃会触发系统重启(因它是所有 IPC 通信的基础,不可缺失)。 - 轻量级设计:仅负责 “服务注册 / 查询”,不处理具体业务逻辑,代码量少(约几千行 C 代码),运行效率高,不会成为性能瓶颈。
- 权限控制:注册服务(
addService)需要系统级权限(如android.permission.ADD_SYSTEM_SERVICE),普通 App 进程无法注册服务,保障系统安全。
总结
ServiceManager 是 Android 系统 Binder 通信的 “核心枢纽”,其核心价值是 解决 “进程间找不到对方 Binder 实例” 的问题,通过 “注册 - 查询” 机制实现服务的统一管理。它启动早、轻量级、高可靠,是所有跨进程调用(如 App 调用系统服务、系统服务间交互)的基础。理解 ServiceManager 的工作原理,是掌握 Android IPC 通信和系统服务调用的关键前提。
资料
Android面试:挂了三次的ServiceManager 工作原理,这次怎么也得整的明明白白!
Android系统--ServiceManager服务