注册服务
在Android中,每个进程获取系统提供的各种系统服务(AMS,PMS,WMS等)都是需要通过ServiceManager才可以。而这些系统服务进行Binder注册,也需要获取ServiceManager服务才可以。 在刚才我们讲过,ServiceManager在启动时候也会通过become_context_manager将自己也注册成为一个Binder服务。 在回答这个问题的时候,我们紧扣2个点
- 找到ServiceManger服务
- 添加服务到ServiceManger
首先Java层发起的获取服务,在native层经过一系列操作,最后把对应服务端的代理BinderProxy(BpBinder)返回出来(会从缓存中取,没有则创建) (binder部分后续再聊)
找到服务
以java层添加 震动服务为例
在addService时候 我们需要getIServiceManager(), 核心代码如下
在 getIServiceManager()中,切入到native方法中 BinderInternal.getContextObject() -> ProcessState::getStrongProxyForHandle(0) 传入 handle 0 这个就是上面提到ServiceManger初始化时候在binder注册的服务handle值 然后最终返回到Java层 拿到ServiceManager对应的BpBinder对象
下面展示
- ProcessState里维护了一个单例,每个进程只有一个ProcessState对象,创建ProcessState时候就会去打开Binder驱动,同时会设置Binder线程池里线程个数等其它参数
- Native层构造BpBinder(handle=0表示该BpBinder是ServiceManager在客户端的引用),再构造BinderProxyNativeData持有BpBinder。
- 构造BinderProxy对象并持有BinderProxyNativeData,也就是间接持有BpBinder
- 最后构造了ServiceManagerProxy对象,它实现了IServiceManager接口,它的成员变量mRemote指向了BinderProxy
注册服务
getIServiceManager()获取到servicemanger的 bpBinder之后,调用addService方法了, 最终会将这个服务的handle句柄值(BpBinder)和 name 构造成svcinfo注册进入上述的svclist链表中, 完成服务的添加。
具体细节如下,可以了解下
驱动建立服务handle和BBinder对象指针的映射关系,并将服务的名字和服务的handle传递给ServiceManager(通过ServiceManager handle查找)。 ServiceManager拿到消息后建立映射关系,等待其它进程的请求。
到这里 添加服务到ServiceManager中了
再来个图帮助理解