欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > 名人名企 > 一文学习Android系统核心服务ServiceManager

一文学习Android系统核心服务ServiceManager

2024/11/30 10:53:56 来源:https://blog.csdn.net/wudexiaoade2008/article/details/143997663  浏览:    关键词:一文学习Android系统核心服务ServiceManager

ServiceManager 是 Android 系统中核心的系统服务注册与发现机制,它在 Android Framework 层扮演服务注册中心的角色。它允许进程通过它注册、查询和使用系统服务,实现进程间通信 (IPC) 的基础架构。

ServiceManager 的作用

  1. 服务注册:应用程序或系统组件可以将一个 Binder 对象作为服务注册到 ServiceManager 中。
  2. 服务发现:客户端可以通过 ServiceManager 查询所需服务的 Binder 接口。
  3. IPC 中转:它为 Android 的 Binder IPC 提供了一个全局目录,用于绑定客户端和服务端。

在这里插入图片描述

工作原理

  1. ServiceManager 的启动
  • 在 Android 系统启动过程中,init 进程启动 servicemanager 可执行文件(实现是 C++ 代码)。
  • servicemanager 会在内核中注册为一个 Binder 服务,并接受来自其他进程的服务注册和查询请求。
  1. 服务注册
  • 服务端(通常是系统服务,如 ActivityManagerService)通过 addService() 方法向 ServiceManager 注册服务。
  • ServiceManager 将服务的名称与对应的 Binder 引用存储在内部表中。
  1. 服务查询
  • 客户端通过 getService() 方法向 ServiceManager 查询服务。
  • 如果服务存在,ServiceManager 返回对应的 Binder 引用;如果不存在,则客户端可以选择等待服务的注册。
  1. 服务使用
  • 客户端通过得到的 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 的重要特点

  1. 全局唯一性:整个 Android 系统中只有一个 ServiceManager 实例,确保服务注册和查询的一致性。
  2. Binder 支持:作为 Android IPC 的核心机制,ServiceManager 利用 Binder 进行服务端和客户端的连接。
  3. 按需启动:只有当客户端尝试访问未启动的服务时,ServiceManager 会通知系统启动该服务。

源码分析

ServiceManager 的核心实现主要分为两个部分:

  1. Native 实现:通过 servicemanager 守护进程,用 C++ 实现。
    • 源码位置:frameworks/native/cmds/servicemanager/
  2. 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;
}
关键步骤:
  1. 创建 Binder 驱动实例
  • 通过 ProcessState::self() 获取 Binder 驱动的全局实例。
  1. 注册 ServiceManager
  • 使用 setContextObject() 将 ServiceManager 注册为 Binder 驱动的上下文对象。
  1. 启动线程池
  • 调用 startThreadPool() 开启 Binder IPC 线程池,准备处理请求。
  1. 进入服务循环
  • 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 系统正常运行的重要环节。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com