当前位置: 首页 > news >正文

一文学习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 系统正常运行的重要环节。


http://www.mrgr.cn/news/77891.html

相关文章:

  • 《TCP/IP网络编程》学习笔记 | Chapter 15:套接字与标准 I/O
  • Android中的依赖注入(DI)框架Hilt
  • 【Python运维】从零开始:用Python构建自动化部署工具
  • [RabbitMQ] 重试机制+TTL+死信队列
  • leetcode 919.完全二叉树插入器
  • Nmap识别MongoDB 6.0指纹
  • VMware ubuntu创建共享文件夹与Windows互传文件
  • 分词器的概念(通俗易懂版)
  • CPU命名那些事
  • SQL进阶技巧:如何分析互逆记录?| 相互关注为例分析
  • 动态规划算法--01背包问题详细讲解步骤
  • 【排序算法 python实现】
  • 【大数据分析机器学习】分布式机器学习
  • C++ For Hot100
  • 机器学习周志华学习笔记-第6章<支持向量机>
  • 【C语言】连接陷阱探秘(3):形参、实参与返回值
  • flux的权重版本
  • Ubuntu下安装Qt
  • 【C++知识总结1】c++第一篇,简单了解一下命名空间是什么
  • Linux: C语言解析域名
  • 使用猴子补丁对pytorch的分布式接口进行插桩
  • 鸿蒙进阶篇-状态管理之@Prop@Link
  • 机器学习周志华学习笔记-第4章<决策树>
  • Android Framework WMS面试题及参考答案
  • YOLOv11融合[NeurlS2022]递归门控卷积gnconv模块及相关改进思路
  • 深度优先搜索(dfs)题目合集