Service组件在启动时,需要将自己注册到ServiceManager中;而Client组件在使用Service组件提供的服务之前,也需要通过ServiceManager来获得Serivce组件的代理对象。由于ServiceManager本身也是一个Service组件, 因此,其他的Service组件和Client组件在使用它提供的服务之前, 也需要先获得它的代理对象。作为一个特殊的Service组件, ServiceManager代理对象的获取过程与其他的Service代理对象的获取过程有所不同,ServiceManager代理对象的类型为BpServiceManager。
IServiceManager接口定义了四个成员函数getService、checkService、addService和listService, 其中, getService和checkService用来获取Service组件的代理对象, addService用来注册Service组件,listService用来获取注册在Service Manager中的Service组件名称列表。
对于一般的Service组件来说,Client进程首先要通过Binder驱动程序来获得它的一个句柄值,然后才可以根据这个句柄创建一个Binder代理对象,最后将这个Binder代理对象封装成一个实现了特定接口的代理对象。由于Service Manager的句柄值恒为0, 因此, 获取它的一个代理对象的过程就省去了与Binder驱动程序交互的过程。Android系统在应用程序框架层的Binder库中提供了一个函数defaultServiceManager来获得一个Service。
对于一般的Service组件来说,Client进程首先要通过Binder驱动程序来获得它的一个句柄值,然后才可以根据这个句柄创建一个Binder代理对象,最后将这个Binder代理对象封装成一个实现了特定接口的代理对象。由于Service Manager的句柄值恒为0, 因此, 获取它的一个代理对象的过程就省去了与Binder驱动程序交互的过程。
Android系统在应用程序框架层的Binder库中提供了一个函数defaultServiceManager来获得一个ServiceManager的代理对象。
IServiceManager.defaultServiceManager
代码路径:/frameworks/native/cmds/servicemanager/servicemanager.rc
(http://androidxref.com/8.0.0_r4/xref/frameworks/native/cmds/servicemanager/servicemanager.rc)
34sp<IServiceManager> defaultServiceManager() 35{ 36 if (gDefaultServiceManager != NULL) return gDefaultServiceManager;//检查全局变量gDefaultServiceManager是否不等于NULL 37 //如果是, 那么就说明Binder库已经为进程创建过一个Service Manager代理对象,直接将它返回给调用者 38 { 39 AutoMutex _l(gDefaultServiceManagerLock); 40 while (gDefaultServiceManager == NULL) { 41 gDefaultServiceManager = interface_cast<IServiceManager>( 42 ProcessState::self()->getContextObject(NULL)); 43 if (gDefaultServiceManager == NULL) 44 sleep(1); 45 } 46 } 47 48 return gDefaultServiceManager; 49}
全局变量gDefaultServiceManager是一个类型为IServiceManager的强指针,它指向进程内的一个BpServiceManager对象, 即一个ServiceManager代理对象;而全局变量gDefaultServiceManagerLock是一个互斥锁, 是用来保证一个进程至多只有一个Service Manager代理对象的。
在41行是三次函数调用。
第一次是调用ProcessState类的静态成员函数self获得进程内的一个ProcessState对象;
第二次是调用前面获得的ProcessState对象的成员函数getContextObject创建一个Binder代理对象;
第三次是调用模板函数interface_cast<IServiceManager>将前面获得的Binder代理对象封装成一个ServiceManager代理对象。