【Android基础回顾】四:ServiceManager

Android 中的 ServerManager 是 Android 框架中一个用于管理系统服务的核心机制。它是 Binder IPC 的一部分,用于在客户端和服务端之间建立联系,广泛应用于系统服务(如 ActivityManager、WindowManager 等)的注册与获取。

1 ServiceManager职责是什么?有什么用?

ServiceManager 是 Android 系统中一个特殊的 Binder 服务,其职责主要是:

服务注册(addService)

服务查找(getService、checkService)

服务列举(listServices)

它是所有系统服务的"目录服务",作用类似一个全局的"服务注册表"。

2 ServiceManager的关键模块有哪些?

2.1 ServiceManager 本身(Native C++)

位于 frameworks/native/cmds/servicemanager/,其本质是一个 Binder 服务,负责接收请求(添加、查找服务)并处理。

java 复制代码
int main() {
    sp<ServiceManager> sm = new ServiceManager();  // 实例化
    sm->addService(...); // 注册服务
    ...
    IPCThreadState::self()->joinThreadPool(); // 进入 Binder 循环
}

2.2 IServiceManager 接口

是客户端与服务端交互的 Binder 接口定义,定义了如下方法:

addService(name, service)

getService(name)

checkService(name)

listServices()

2.3 defaultServiceManager()(C++)

客户端通过该方法获取 ServiceManager 的代理对象。

java 复制代码
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder = sm->getService(String16("activity"));

2.4 Java 层封装

Java 层通过 android.os.ServiceManager 访问 native 的 ServiceManager:

java 复制代码
IBinder binder = ServiceManager.getService("activity");

内部通过 JNI 调用 native 层 BinderInternal.getContextObject() 获得 binder 代理。

3 注册与获取服务流程

3.1 注册服务(addService)

系统服务启动时调用 ServiceManager.addService(name, binder)

binder 驱动将请求转发给 native 的 ServiceManager

ServiceManager 保存服务到本地表中(map)

3.2 获取服务(getService)

客户端调用 ServiceManager.getService(name)

binder 驱动将请求传给 native ServiceManager

查找到对应 binder 实例返回。

Q&A

怎么理解"ServiceManager 是 Android 系统中一个特殊的 Binder 服务"?

这里面有两个关键词。

一是binder服务,Binder 是 Android 的核心 IPC(进程间通信)机制。在 Binder 架构中,"服务" 是一个实现了 Binder 接口的对象(IBinder),可以被其他进程远程调用。每个服务都通过 Binder 驱动注册到内核,并能被其他进程通过 Binder 通信访问。

二是"特殊",特殊性在哪?ServiceManager 就是一个这样的 Binder 服务对象,但它比一般服务更特殊。原因如下:

  1. 它是 Binder 世界的"入口"
    所有系统服务(如 ActivityManager、WindowManager 等)在启动后都先注册到 ServiceManager 中。
    客户端想用这些服务时,必须通过 ServiceManager 查询到对应的 Binder 接口。👉 它充当了一个"Binder 服务注册与发现中心"(相当于服务注册表)。
  2. 由系统早期启动并驻留内存。它在 init 进程阶段由 native 层以独立可执行程序的形式(servicemanager)启动。启动时会进入一个 Binder 循环线程池,不断处理其他进程通过 Binder 发来的服务注册/查询请求。
  3. 权限控制 & 本地注册表,仅系统进程才能注册服务,防止恶意进程篡改系统服务。ServiceManager 会维护一个本地服务表(map),键是服务名,值是对应的 IBinder 实现。

普通的client进程和service进程想要通过AIDL通讯,需要注册到ServiceManager吗?

这里有两种场景,先说第一种,系统服务场景(系统进程 + 普通 app)。

比如我们想通过 AIDL 访问 ActivityManager、WindowManager,这些系统服务会在系统启动时通过 ServiceManager.addService() 注册自己。

普通 App 调用 ServiceManager.getService("activity"),获得其 Binder 接口。

系统服务在系统启动的时候会注册到 ServiceManager,这是它们能被系统和 app 找到的前提。

第二种场景,自定义服务场景(普通 App 进程 + 普通 App 进程)。

我们自己写一个 AIDL 服务并运行在一个 Service 中,想让其他 App 调用它:这种情况不需要也无法使用ServiceManager注册我们自己的服务,因为ServiceManager 是系统服务,不对第三方应用开放 addService() 权限。通常用 绑定服务(bindService) 的方式建立连接。

流程是这样的,服务端在 AndroidManifest.xml 中声明一个 Service,并实现 AIDL 接口。

客户端通过 Intent(带包名和 Service 类名)调用 bindService()。系统通过 AMS(ActivityManagerService)管理服务绑定,并将 Binder 对象通过回调传给客户端(onServiceConnected())。

所以这种场景下,不是通过 ServiceManager 查找,而是通过 AMS 的服务绑定机制传递 Binder 对象。

持续更新。。。

相关推荐
小草帽学编程2 小时前
鸿蒙Next开发真机调试签名申请流程
android·华为·harmonyos
dog shit3 小时前
web第十次课后作业--Mybatis的增删改查
android·前端·mybatis
科技道人5 小时前
Android15 launcher3
android·launcher3·android15·hotseat
CYRUS_STUDIO9 小时前
FART 脱壳某大厂 App + CodeItem 修复 dex + 反编译还原源码
android·安全·逆向
Think Spatial 空间思维12 小时前
【实施指南】Android客户端HTTPS双向认证实施指南
android·网络协议·https·ssl
louisgeek13 小时前
Git 使用 SSH 连接
android
二流小码农13 小时前
鸿蒙开发:实现一个标题栏吸顶
android·ios·harmonyos
八月林城14 小时前
echarts在uniapp中使用安卓真机运行时无法显示的问题
android·uni-app·echarts
雨白14 小时前
搞懂 Fragment 的生命周期
android