
在Android的跨进程通信(IPC)体系中,Binder是核心机制,而ServiceManager则是Binder世界的"服务中介"------它负责管理系统中所有公开的Binder服务,让客户端(Client)能精准定位到对应的服务端(Server)。
核心角色
在Binder服务交互中,有4个不可替代的角色:
- ServiceManager :独立运行在
servicemanager进程,是系统级"服务注册表",负责存储"服务名-Binder代理"的映射关系。 - Server:服务提供者(如ActivityManagerService、WindowManagerService),通过Binder对外暴露功能。
- Client:服务调用者(如普通应用进程),需要通过Binder调用Server的功能。
- Binder驱动 :内核层组件,是跨进程通信的"中转桥梁",负责进程间的数据转发、资源管理。

Server端
Client能查到Server,前提是Server已经把自己"注册"到ServiceManager中,流程如下:
-
Server获取ServiceManager的代理
ServiceManager本身是系统中第一个Binder服务,其Binder实体在Binder驱动中的标识(handle)固定为
0。Server通过
defaultServiceManager()方法,借助Binder驱动(以handle 0为标识),获取到ServiceManager的Binder代理对象(Client/Server与ServiceManager通信,都依赖这个代理)。 -
Server向ServiceManager注册服务
Server调用ServiceManager代理的
addService(String serviceName, IBinder service)方法,传入两个关键信息:serviceName:服务的唯一标识(如AMS对应"activity",WMS对应"window");IBinder service:Server自身的Binder实体(即提供服务的实际对象)。
-
Binder驱动与ServiceManager的存储
Binder驱动会为Server的Binder实体分配一个唯一的
handle(进程内唯一标识),然后ServiceManager将"服务名-该Binder实体的代理(包含handle)"存入自身的服务注册表。
Client端
当Server完成注册后,Client就能通过ServiceManager查询到对应的服务,流程如下:
-
Client同样获取ServiceManager代理
和Server逻辑一致:Client通过
defaultServiceManager()方法,借助Binder驱动(handle 0),拿到ServiceManager的Binder代理。 -
Client发起服务查询
Client调用ServiceManager代理的
getService(String serviceName)方法,传入要找的服务名(比如要调用AMS,就传"activity")。 -
ServiceManager返回Binder代理
ServiceManager从自己的注册表中,找到该服务名对应的Binder代理(包含Server的Binder实体handle),并通过Binder驱动将这个代理传递给Client。
-
Client用代理与Server通信
Client拿到的Binder代理,本质是Server的"远程引用"------后续Client调用服务方法(比如
startActivity())时,这个代理会把调用请求交给Binder驱动,驱动根据handle找到对应的Server进程和Binder实体,完成跨进程调用的转发。
底层关键
Client、Server、ServiceManager分属不同进程,能完成交互全靠Binder驱动的核心能力:
- 突破进程隔离:Binder驱动是内核组件,可直接访问各进程地址空间,采用"一次内存拷贝"优化(比传统IPC更高效),实现跨进程数据传递。
- handle映射管理:每个进程维护自己的handle表,Binder驱动负责将不同进程的handle,映射到同一个Binder实体。
- 调用转发:当Client通过代理调用方法时,驱动会根据handle定位到Server进程的Binder实体,将调用请求转发过去,并把返回结果带回Client。
实际例子
当普通应用要启动Activity时,Client(应用进程)的操作是:
- 调用
defaultServiceManager().getService("activity"),从ServiceManager拿到AMS的Binder代理; - 通过该代理调用
startActivity()方法; - Binder驱动将调用转发到AMS进程(Server),AMS处理后再通过驱动返回结果。
