rokevin
移动
前端
语言
  • 基础

    • Linux
    • 实施
    • 版本构建
  • 应用

    • WEB服务器
    • 数据库
  • 资讯

    • 工具
    • 部署
开放平台
产品设计
  • 人工智能
  • 云计算
计算机
其它
GitHub
移动
前端
语言
  • 基础

    • Linux
    • 实施
    • 版本构建
  • 应用

    • WEB服务器
    • 数据库
  • 资讯

    • 工具
    • 部署
开放平台
产品设计
  • 人工智能
  • 云计算
计算机
其它
GitHub
  • ServiceManager

ServiceManager

ServiceManager 是 Android 系统中 Binder 通信的 “服务注册表”,负责管理所有系统服务(如 AMS、WMS)的 Binder 引用,为进程间通信(IPC)提供 “服务查询与注册” 的核心能力。所有进程(包括 App 进程、SystemServer 进程)都需通过 ServiceManager 找到目标服务的 Binder 代理,才能发起跨进程调用。

ServiceManager 的核心定位与作用

在 Android 的 Binder 通信模型中,进程间无法直接找到对方的 Binder 实例,必须通过一个 “中间枢纽” 来匹配 “服务提供者” 和 “服务使用者”—— 这个枢纽就是 ServiceManager。其核心作用可概括为 “两个核心动作”:

  1. 服务注册(addService):系统服务(如 AMS)启动后,将自身的 Binder 实例注册到 ServiceManager,并关联一个唯一的 “服务名称”(如 AMS 对应 "activity")。
  2. 服务查询(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/),核心初始化逻辑如下:

  1. 打开 Binder 驱动:调用 open("/dev/binder", O_RDWR) 打开 Linux 内核的 Binder 驱动设备文件(/dev/binder 是 Binder 通信的内核层入口),获取 Binder 设备描述符。

  2. 注册为 “上下文管理者”(Context Manager):调用ioctl(fd, BINDER_SET_CONTEXT_MGR, 0) 向 Binder 驱动注册,声明自己是 “服务上下文管理者”—— 这是 ServiceManager 的专属身份,其他进程无法抢占。

    此步骤的核心作用:让 Binder 驱动知道 “所有服务注册 / 查询请求,都要转发给 ServiceManager 处理”。

  3. 初始化 socket 监听:绑定并监听之前 init 进程创建的 service_manager socket,等待接收其他进程的服务注册 / 查询请求。

阶段 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 实例注册到 ServiceManagerSystemServer 进程服务名称(如 "activity")、Binder 句柄、权限标识
getService根据服务名称查询对应的 Binder 代理(Proxy)App 进程、其他系统进程服务名称(如 "window")
listServices查询当前已注册的所有系统服务名称(用于调试或系统工具)调试工具、系统进程无(或权限参数)

示例:App 进程调用 startActivity() 时,底层逻辑是:

  1. App 进程通过 getService("activity") 向 ServiceManager 查询 AMS 的 Binder 代理。
  2. ServiceManager 从哈希表中找到 "activity" 对应的 Binder 句柄,生成代理返回给 App 进程。
  3. 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 的关键特性

  1. Native 层实现:ServiceManager 是纯 Native 进程(C/C++ 编写),不依赖 Java 虚拟机,启动速度快,可在系统早期提供服务(早于 Zygote 和 SystemServer)。
  2. 关键进程属性:在 init.rc 中标记为 critical(关键进程),若崩溃会触发系统重启(因它是所有 IPC 通信的基础,不可缺失)。
  3. 轻量级设计:仅负责 “服务注册 / 查询”,不处理具体业务逻辑,代码量少(约几千行 C 代码),运行效率高,不会成为性能瓶颈。
  4. 权限控制:注册服务(addService)需要系统级权限(如 android.permission.ADD_SYSTEM_SERVICE),普通 App 进程无法注册服务,保障系统安全。

总结

ServiceManager 是 Android 系统 Binder 通信的 “核心枢纽”,其核心价值是 解决 “进程间找不到对方 Binder 实例” 的问题,通过 “注册 - 查询” 机制实现服务的统一管理。它启动早、轻量级、高可靠,是所有跨进程调用(如 App 调用系统服务、系统服务间交互)的基础。理解 ServiceManager 的工作原理,是掌握 Android IPC 通信和系统服务调用的关键前提。

资料

Android面试:挂了三次的ServiceManager 工作原理,这次怎么也得整的明明白白!
Android系统--ServiceManager服务

最近更新:: 2025/10/28 00:33
Contributors: luokaiwen, 罗凯文