您好,欢迎访问三七文档
当前位置:首页 > 电子/通信 > 综合/其它 > Android系统进程间通信Binder机制在应用程序框架层的Java接口源代码
在前面几篇文章中,我们详细介绍了Android系统进程间通信机制Binder的原理,并且深入分析了系统提供的Binder运行库和驱动程序的源代码。细心的读者会发现,这几篇文章分析的Binder接口都是基于C/C++语言来实现的,但是我们在编写应用程序都是基于Java语言的,那么,我们如何使用Java语言来使用系统的Binder机制来进行进程间通信呢?这就是本文要介绍的Android系统应用程序框架层的用Java语言来实现的Binder接口了。熟悉Android系统的读者,应该能想到应用程序框架中的基于Java语言的Binder接口是通过JNI来调用基于C/C++语言的Binder运行库来为Java应用程序提供进程间通信服务的了。JNI在Android系统中用得相当普遍,SDK中的Java接口API很多只是简单地通过JNI来调用底层的C/C++运行库从而为应用程序服务的。这里,我们仍然是通过具体的例子来说明Binder机制在应用程序框架层中的Java接口,主要就是ServiceManager、Server和Client这三个角色的实现了。通常,在应用程序中,我们都是把Server实现为Service的形式,并且通过IServiceManager.addService接口来把这个Service添加到ServiceManager,Client也是通过IServiceManager.getService接口来获得Service接口,接着就可以使用这个Service提供的功能了,这个与运行时库的Binder接口是一致的。前面我们学习Android硬件抽象层时,曾经在应用程序框架层中提供了一个硬件访问服务HelloService,这个Service运行在一个独立的进程中充当Server的角色,使用这个Service的Client运行在另一个进程中,它们之间就是通过Binder机制来通信的了。这里,我们就使用HelloService这个例子来分析Android系统进程间通信Binder机制在应用程序框架层的Java接口源代码。所以希望读者在阅读下面的内容之前,先了解一下前面在Ubuntu上为Android系统的ApplicationFrameworks层增加硬件访问服务这篇文章。这篇文章通过五个情景来学习Android系统进程间通信Binder机制在应用程序框架层的Java接口:1.获取ServiceManager的Java远程接口的过程;2.HelloService接口的定义;3.HelloService的启动过程;4.Client获取HelloService的Java远程接口的过程;5.Client通过HelloService的Java远程接口来使用HelloService提供的服务的过程。一.获取ServiceManager的Java远程接口我们要获取的ServiceManager的Java远程接口是一个ServiceManagerProxy对象的IServiceManager接口。我们现在就来看看ServiceManagerProxy类是长什么样子的:这里可以看出,ServiceManagerProxy类实现了IServiceManager接口,IServiceManager提供了getService和addService两个成员函数来管理系统中的Service。从ServiceManagerProxy类的构造函数可以看出,它需要一个BinderProxy对象的IBinder接口来作为参数。因此,要获取ServiceManager的Java远程接口ServiceManagerProxy,首先要有一个BinderProxy对象。下面将会看到这个BinderProxy对象是如何获得的。再来看一下是通过什么路径来获取ServiceManager的Java远程接口ServiceManagerProxy的。这个主角就是ServiceManager了,我们也先看一下ServiceManager是长什么样子的:ServiceManager类有一个静态成员函数getIServiceManager,它的作用就是用来获取ServiceManager的Java远程接口了,而这个函数又是通过ServiceManagerNative来获取ServiceManager的Java远程接口的。接下来,我们就看一下ServiceManager.getIServiceManager这个函数的实现,这个函数定义在frameworks/base/core/java/android/os/ServiceManager.java文件中:viewplain1.publicfinalclassServiceManager{2.......3.privatestaticIServiceManagersServiceManager;4.......5.privatestaticIServiceManagergetIServiceManager(){6.if(sServiceManager!=null){7.returnsServiceManager;8.}9.10.//Findtheservicemanager11.sServiceManager=ServiceManagerNative.asInterface(BinderInternal.getContextObject());12.returnsServiceManager;13.}14.......15.}如果其静态成员变量sServiceManager尚未创建,那么就调用ServiceManagerNative.asInterface函数来创建。在调用ServiceManagerNative.asInterface函数之前,首先要通过BinderInternal.getContextObject函数来获得一个BinderProxy对象。我们来看一下BinderInternal.getContextObject的实现,这个函数定义在frameworks/base/core/java/com/android/internal/os/BinderInternal.java文件中:viewplain1.publicclassBinderInternal{2.......3./**4.*Returntheglobalcontextobjectofthesystem.Thisisusually5.*animplementationofIServiceManager,whichyoucanusetofind6.*otherservices.7.*/8.publicstaticfinalnativeIBindergetContextObject();9.10.......11.}这里可以看出,BinderInternal.getContextObject是一个JNI方法,它实现在frameworks/base/core/jni/android_util_Binder.cpp文件中:viewplain1.staticjobjectandroid_os_BinderInternal_getContextObject(JNIEnv*env,jobjectclazz)2.{3.spIBinderb=ProcessState::self()-getContextObject(NULL);4.returnjavaObjectForIBinder(env,b);5.}这里看到我们熟悉的ProcessState::self()-getContextObject函数,具体可以参考浅谈Android系统进程间通信(IPC)机制Binder中的Server和Client获得ServiceManager接口之路一文。ProcessState::self()-getContextObject函数返回一个BpBinder对象,它的句柄值是0,即下面语句:viewplain1.spIBinderb=ProcessState::self()-getContextObject(NULL);相当于是:viewplain1.spIBinderb=newBpBinder(0);接着调用javaObjectForIBinder把这个BpBinder对象转换成一个BinderProxy对象:viewplain1.jobjectjavaObjectForIBinder(JNIEnv*env,constspIBinder&val)2.{3.if(val==NULL)returnNULL;4.5.if(val-checkSubclass(&gBinderOffsets)){6.//Oneofourown!7.jobjectobject=static_castJavaBBinder*(val.get())-object();8.//printf(objectForBinder%p:it'sourown%p!\n,val.get(),object);9.returnobject;10.}11.12.//Fortherestofthefunctionwewillholdthislock,toserialize13.//looking/creationofJavaproxiesfornativeBinderproxies.14.AutoMutex_l(mProxyLock);15.16.//Someoneelse's...doweknowaboutit?17.jobjectobject=(jobject)val-findObject(&gBinderProxyOffsets);18.if(object!=NULL){19.jobjectres=env-CallObjectMethod(object,gWeakReferenceOffsets.mGet);20.if(res!=NULL){21.LOGV(objectForBinder%p:foundexisting%p!\n,val.get(),res);22.returnres;23.}24.LOGV(Proxyobject%pofIBinder%pnolongerinworkingset!!!,object,val.get());25.android_atomic_dec(&gNumProxyRefs);26.val-detachObject(&gBinderProxyOffsets);27.env-DeleteGlobalRef(object);28.}29.30.object=env-NewObject(gBinderProxyOffsets.mClass,gBinderProxyOffsets.mConstructor);31.if(object!=NULL){32.LOGV(objectForBinder%p:creatednew%p!\n,val.get(),object);33.//Theproxyholdsareferencetothenativeobject.34.env-SetIntField(object,gBinderProxyOffsets.mObject,(int)val.get());35.val-incStrong(object);36.37.//Thenativeobjectneedstoholdaweakreferencebacktothe38.//proxy,sowecanretrievethesameproxyifitisstillactive.39.jobjectrefObject=env-NewGlobalRef(40.env-GetObjectField(object,gBinderProxyOffsets.mSelf));41.val-attachObject(&gBinderProxyOffsets,refObject,42.j
本文标题:Android系统进程间通信Binder机制在应用程序框架层的Java接口源代码
链接地址:https://www.777doc.com/doc-309145 .html