ServiceManager
是 Android 系统中核心的系统服务注册与发现机制,它在 Android Framework 层扮演服务注册中心的角色。它允许进程通过它注册、查询和使用系统服务,实现进程间通信 (IPC) 的基础架构。
ServiceManager 的作用
- 服务注册:应用程序或系统组件可以将一个 Binder 对象作为服务注册到 ServiceManager 中。
- 服务发现:客户端可以通过 ServiceManager 查询所需服务的 Binder 接口。
- IPC 中转:它为 Android 的 Binder IPC 提供了一个全局目录,用于绑定客户端和服务端。
工作原理
- ServiceManager 的启动
- 在 Android 系统启动过程中,init 进程启动 servicemanager 可执行文件(实现是 C++ 代码)。
- servicemanager 会在内核中注册为一个 Binder 服务,并接受来自其他进程的服务注册和查询请求。
- 服务注册
- 服务端(通常是系统服务,如 ActivityManagerService)通过 addService() 方法向 ServiceManager 注册服务。
- ServiceManager 将服务的名称与对应的 Binder 引用存储在内部表中。
- 服务查询
- 客户端通过 getService() 方法向 ServiceManager 查询服务。
- 如果服务存在,ServiceManager 返回对应的 Binder 引用;如果不存在,则客户端可以选择等待服务的注册。
- 服务使用
- 客户端通过得到的 Binder 引用直接与服务端通信,不需要再经过 ServiceManager。
ServiceManager 的核心接口
1. 注册服务
IBinder myBinder = new MyBinder();
ServiceManager.addService("my_service_name", myBinder);
- addService(String name, IBinder service) 方法用于将服务注册到 ServiceManager。
2. 查询服务
IBinder binder = ServiceManager.getService("my_service_name");
- getService(String name) 方法用于根据服务名获取对应的 Binder 接口。
3. 列举所有服务
String[] serviceList = ServiceManager.listServices();
- listServices() 方法返回当前已注册服务的名称列表。
ServiceManager 的架构图
+----------------+
| Client App |
+----------------+|| getService("service_name")v
+----------------+
| ServiceManager |
+----------------+|| addService("service_name", IBinder)v
+--------------------+
| System Services |
| (e.g., AMS, WMS) |
+--------------------+
ServiceManager 的重要特点
- 全局唯一性:整个 Android 系统中只有一个 ServiceManager 实例,确保服务注册和查询的一致性。
- Binder 支持:作为 Android IPC 的核心机制,ServiceManager 利用 Binder 进行服务端和客户端的连接。
- 按需启动:只有当客户端尝试访问未启动的服务时,ServiceManager 会通知系统启动该服务。
源码分析
ServiceManager 的核心实现主要分为两个部分:
- Native 实现:通过 servicemanager 守护进程,用 C++ 实现。
- 源码位置:frameworks/native/cmds/servicemanager/
- Java 层接口:提供给应用开发者使用的 ServiceManager 类。
- 源码位置:frameworks/base/core/java/android/os/ServiceManager.java
示例代码
ServiceManager
的内部实现依赖于 Binder 机制:
// 注册服务
public static void addService(String name, IBinder service) {try {getIServiceManager().addService(name, service, false);} catch (RemoteException e) {throw e.rethrowFromSystemServer();}
}// 查询服务
public static IBinder getService(String name) {try {return getIServiceManager().getService(name);} catch (RemoteException e) {return null;}
}
总结
ServiceManager
是 Android 系统中连接系统服务与客户端的桥梁,其稳定性直接影响整个系统的运行。理解其工作机制有助于更深入地掌握 Android 的服务框架以及 IPC 的实现原理。
以下详细介绍下ServiceManager的启动过程
init 进程启动 servicemanager 的过程
init
是 Android 系统的第一个用户态进程,它的主要职责之一是启动系统所需的各种服务,包括 servicemanager
。以下是 init
启动 servicemanager
的详细过程。
1. init 进程的角色
- init 是 Android 的启动管理器,负责解析 init.rc 文件中的配置信息并启动所需服务。
- servicemanager 是一个核心守护进程,通过 init.rc 的配置由 init 直接启动。
2. init.rc 文件的配置
servicemanager
的启动方式是在 Android 的 init.rc
文件中定义的。具体配置内容如下:
service servicemanager /system/bin/servicemanagerclass coreuser systemgroup systemcriticalonrestart restart zygote
配置说明:
- service servicemanager:定义服务名称为 servicemanager。
- /system/bin/servicemanager:指向 servicemanager 可执行文件的路径。
- class core:表示这是一个核心服务,系统启动时优先运行。
- user system:以 system 用户身份运行。
- group system:属于 system 用户组。
- critical:标记为关键服务,如果退出会触发系统重启。
- onrestart restart zygote:如果 servicemanager 重启,zygote 也会随之重启。
3. 启动过程分析
步骤 1:init 进程启动
- Android 启动时,内核加载并启动 init 进程。
- init 进程会解析默认的 init.rc 文件。
步骤 2:解析 init.rc
- init.rc 文件包含服务的启动定义,包括 servicemanager。
- 当 init 遇到 service servicemanager 条目时,会按照配置创建并启动 servicemanager。
步骤 3:启动 servicemanager
- init 使用以下步骤启动 servicemanager:Fork 一个新进程。在子进程中执行 /system/bin/servicemanager 二进制文件。配置进程的用户和组权限。
步骤 4:servicemanager 的初始化
- servicemanager 启动后,完成以下任务:初始化 Binder 驱动并注册自己为 Binder 服务(BINDER_SERVICE_MANAGER)。开始监听客户端请求,处理服务注册和查询。
4. ServiceManager 初始化细节
/system/bin/servicemanager
的主要功能是初始化 Binder 并启动服务循环:
核心代码片段
servicemanager
的主要逻辑在 frameworks/native/cmds/servicemanager/
中:
int main(int argc, char** argv) {sp proc = ProcessState::self();sp sm = new ServiceManager();// 注册自己为 BINDER_SERVICE_MANAGERproc->setContextObject(sm);// 启动 Binder 线程池proc->startThreadPool();// 等待客户端请求IPCThreadState::self()->joinThreadPool();return 0;
}
关键步骤:
- 创建 Binder 驱动实例:
- 通过 ProcessState::self() 获取 Binder 驱动的全局实例。
- 注册 ServiceManager:
- 使用 setContextObject() 将 ServiceManager 注册为 Binder 驱动的上下文对象。
- 启动线程池:
- 调用 startThreadPool() 开启 Binder IPC 线程池,准备处理请求。
- 进入服务循环:
- joinThreadPool() 方法阻塞进程,等待处理客户端的服务注册或查询请求。
5. 服务启动的完整时序图
+----------------+ +------------------+ +---------------------+
| Kernel | ---> | init | ---> | servicemanager |
| (启动 init) | | (解析 init.rc) | | (启动并注册 Binder) |
+----------------+ +------------------+ +---------------------+1. Kernel 启动 init
2. init 解析 init.rc 文件
3. 根据 service 配置启动 /system/bin/servicemanager
4. servicemanager 初始化 Binder,并进入服务循环
总结
init
通过解析 init.rc
文件中的 service
配置来启动 servicemanager
,这一过程奠定了 Android 服务架构的基础。作为系统服务的注册和发现中心,servicemanager
的启动是 Android 系统正常运行的重要环节。