538 字
3 分钟
注册服务

注册服务#

在Android中,每个进程获取系统提供的各种系统服务(AMS,PMS,WMS等)都是需要通过ServiceManager才可以。而这些系统服务进行Binder注册,也需要获取ServiceManager服务才可以。 在刚才我们讲过,ServiceManager在启动时候也会通过become_context_manager将自己也注册成为一个Binder服务。 在回答这个问题的时候,我们紧扣2个点

  1. 找到ServiceManger服务
  2. 添加服务到ServiceManger

首先Java层发起的获取服务,在native层经过一系列操作,最后把对应服务端的代理BinderProxy(BpBinder)返回出来(会从缓存中取,没有则创建) (binder部分后续再聊)

找到服务#

以java层添加 震动服务为例 image.png

在addService时候 我们需要getIServiceManager(), 核心代码如下 image.png

在 getIServiceManager()中,切入到native方法中 BinderInternal.getContextObject() -> ProcessState::getStrongProxyForHandle(0) 传入 handle 0 这个就是上面提到ServiceManger初始化时候在binder注册的服务handle值 然后最终返回到Java层 拿到ServiceManager对应的BpBinder对象

下面展示 image.png

  • 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链表中, 完成服务的添加。

具体细节如下,可以了解下 image.png image.png

驱动建立服务handle和BBinder对象指针的映射关系,并将服务的名字和服务的handle传递给ServiceManager(通过ServiceManager handle查找)。 ServiceManager拿到消息后建立映射关系,等待其它进程的请求。

到这里 添加服务到ServiceManager中了 再来个图帮助理解 image.png

注册服务
作者
强人自传
发布于
2020-03-27
许可协议
CC BY-NC-SA 4.0