您好,欢迎访问三七文档
在前面一篇文章浅谈ServiceManager成为Android进程间通信(IPC)机制Binder守护进程之路中,介绍了ServiceManager是如何成为Binder机制的守护进程的。既然作为守护进程,ServiceManager的职责当然就是为Server和Client服务了。那么,Server和Client如何获得ServiceManager接口,进而享受它提供的服务呢?本文将简要分析Server和Client获得ServiceManager的过程。在阅读本文之前,希望读者先阅读Android进程间通信(IPC)机制Binder简要介绍和学习计划一文提到的参考资料Android深入浅出之Binder机制,这样可以加深对本文的理解。我们知道,ServiceManager在Binder机制中既充当守护进程的角色,同时它也充当着Server角色,然而它又与一般的Server不一样。对于普通的Server来说,Client如果想要获得Server的远程接口,那么必须通过ServiceManager远程接口提供的getService接口来获得,这本身就是一个使用Binder机制来进行进程间通信的过程。而对于ServiceManager这个Server来说,Client如果想要获得ServiceManager远程接口,却不必通过进程间通信机制来获得,因为ServiceManager远程接口是一个特殊的Binder引用,它的引用句柄一定是0。获取ServiceManager远程接口的函数是defaultServiceManager,这个函数声明在frameworks/base/include/binder/IServiceManager.h文件中:viewplain1.spIServiceManagerdefaultServiceManager();实现在frameworks/base/libs/binder/IServiceManager.cpp文件中:viewplain1.spIServiceManagerdefaultServiceManager()2.{3.4.if(gDefaultServiceManager!=NULL)returngDefaultServiceManager;5.6.{7.AutoMutex_l(gDefaultServiceManagerLock);8.if(gDefaultServiceManager==NULL){9.gDefaultServiceManager=interface_castIServiceManager(10.ProcessState::self()-getContextObject(NULL));11.}12.}13.14.returngDefaultServiceManager;15.}gDefaultServiceManagerLock和gDefaultServiceManager是全局变量,定义在frameworks/base/libs/binder/Static.cpp文件中:viewplain1.MutexgDefaultServiceManagerLock;2.spIServiceManagergDefaultServiceManager;从这个函数可以看出,gDefaultServiceManager是单例模式,调用defaultServiceManager函数时,如果gDefaultServiceManager已经创建,则直接返回,否则通过interface_castIServiceManager(ProcessState::self()-getContextObject(NULL))来创建一个,并保存在gDefaultServiceManager全局变量中。在继续介绍interface_castIServiceManager(ProcessState::self()-getContextObject(NULL))的实现之前,先来看一个类图,这能够帮助我们了解ServiceManager远程接口的创建过程。参考资料Android深入浅出之Binder机制一文的读者,应该会比较容易理解这个图。这个图表明了,BpServiceManager类继承了BpInterfaceIServiceManager类,BpInterface是一个模板类,它定义在frameworks/base/include/binder/IInterface.h文件中:viewplain1.templatetypenameINTERFACE2.classBpInterface:publicINTERFACE,publicBpRefBase3.{4.public:5.BpInterface(constspIBinder&remote);6.7.protected:8.virtualIBinder*onAsBinder();9.};IServiceManager类继承了IInterface类,而IInterface类和BpRefBase类又分别继承了RefBase类。在BpRefBase类中,有一个成员变量mRemote,它的类型是IBinder*,实现类为BpBinder,它表示一个Binder引用,引用句柄值保存在BpBinder类的mHandle成员变量中。BpBinder类通过IPCThreadState类来和Binder驱动程序并互,而IPCThreadState又通过它的成员变量mProcess来打开/dev/binder设备文件,mProcess成员变量的类型为ProcessState。ProcessState类打开设备/dev/binder之后,将打开文件描述符保存在mDriverFD成员变量中,以供后续使用。理解了这些概念之后,就可以继续分析创建ServiceManager远程接口的过程了,最终目的是要创建一个BpServiceManager实例,并且返回它的IServiceManager接口。创建ServiceManager远程接口主要是下面语句:viewplain1.gDefaultServiceManager=interface_castIServiceManager(2.ProcessState::self()-getContextObject(NULL));看起来简短,却暗藏玄机,具体可阅读Android深入浅出之Binder机制这篇参考资料,这里作简要描述。首先是调用ProcessState::self函数,self函数是ProcessState的静态成员函数,它的作用是返回一个全局唯一的ProcessState实例变量,就是单例模式了,这个变量名为gProcess。如果gProcess尚未创建,就会执行创建操作,在ProcessState的构造函数中,会通过open文件操作函数打开设备文件/dev/binder,并且返回来的设备文件描述符保存在成员变量mDriverFD中。接着调用gProcess-getContextObject函数来获得一个句柄值为0的Binder引用,即BpBinder了,于是创建ServiceManager远程接口的语句可以简化为:viewplain1.gDefaultServiceManager=interface_castIServiceManager(newBpBinder(0));再来看函数interface_castIServiceManager的实现,它是一个模板函数,定义在framework/base/include/binder/IInterface.h文件中:viewplain1.templatetypenameINTERFACE2.inlinespINTERFACEinterface_cast(constspIBinder&obj)3.{4.returnINTERFACE::asInterface(obj);5.}这里的INTERFACE是IServiceManager,于是调用了IServiceManager::asInterface函数。IServiceManager::asInterface是通过DECLARE_META_INTERFACE(ServiceManager)宏在IServiceManager类中声明的,它位于framework/base/include/binder/IServiceManager.h文件中:viewplain1.DECLARE_META_INTERFACE(ServiceManager);展开即为:viewplain1.#defineDECLARE_META_INTERFACE(ServiceManager)\2.staticconstandroid::String16descriptor;\3.staticandroid::spIServiceManagerasInterface(\4.constandroid::spandroid::IBinder&obj);\5.virtualconstandroid::String16&getInterfaceDescriptor()const;\6.IServiceManager();\7.virtual~IServiceManager();IServiceManager::asInterface的实现是通过IMPLEMENT_META_INTERFACE(ServiceManager,android.os.IServiceManager)宏定义的,它位于framework/base/libs/binder/IServiceManager.cpp文件中:viewplain1.IMPLEMENT_META_INTERFACE(ServiceManager,android.os.IServiceManager);展开即为:viewplain1.#defineIMPLEMENT_META_INTERFACE(ServiceManager,android.os.IServiceManager)\2.constandroid::String16IServiceManager::descriptor(android.os.IServiceManager);\3.constandroid::String16&\4.IServiceManager::getInterfaceDescriptor()const{\5.returnIServiceManager::descriptor;\6.}\7.android::spIServiceManagerIServiceManager::asInterface(\8.constandroid::spandroid::IBinder&obj)\9.{\10.android::spIServiceManagerintr;\11.if(obj!=NULL){\12.intr=static_castIServiceManager*(\13.obj-queryLocalInterface(\14.IServiceManager::descriptor).get());\15.if(intr==NULL){\16.intr=newBpServiceManager(obj);\17.}\18.}\19.returnintr;\20.}\21.IServiceManager::IServiceManager(){}\22.IServiceManager::~IServiceManager(){}估计写这段代码的员工是从Microsoft跳槽到Google的。这里我们关注IServiceManager::asInterface的实现:viewplain1.android::spIServiceManagerIServic
本文标题:浅谈Android系统进程间通信(IPC)机制Binder中的Server和Client获得Serv
链接地址:https://www.777doc.com/doc-2312434 .html