`

[Binder.5] 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接口,主要就是Service Manager、Server和Client这三个角色的实现了。通常,在应用程序中,我们都是把Server实现为Service的形式,并且通过IServiceManager.addService接口来把这个Service添加到Service Manager,Client也是通过IServiceManager.getService接口来获得Service接口,接着就可以使用这个Service提供的功能了,这个与运行时库的Binder接口是一致的。

前面我们学习Android硬件抽象层时,曾经在应用程序框架层中提供了一个硬件访问服务HelloService,这个Service运行在一个独立的进程中充当Server的角色,使用这个Service的Client运行在另一个进程中,它们之间就是通过Binder机制来通信的了。这里,我们就使用HelloService这个例子来分析Android系统进程间通信Binder机制在应用程序框架层的Java接口源代码。所以希望读者在阅读下面的内容之前,先了解一下前面在Ubuntu上为Android系统的Application Frameworks层增加硬件访问服务这篇文章。

这篇文章通过五个情景来学习Android系统进程间通信Binder机制在应用程序框架层的Java接口:1. 获取Service Manager的Java远程接口的过程;2. HelloService接口的定义;3. HelloService的启动过程;4. Client获取HelloService的Java远程接口的过程;5.Client通过HelloService的Java远程接口来使用HelloService提供的服务的过程。

一. 获取Service Manager的Java远程接口

我们要获取的Service Manager的Java远程接口是一个ServiceManagerProxy对象的IServiceManager接口。我们现在就来看看ServiceManagerProxy类是长什么样子的:


这里可以看出,ServiceManagerProxy类实现了IServiceManager接口,IServiceManager提供了getService和addService两个成员函数来管理系统中的Service。从ServiceManagerProxy类的构造函数可以看出,它需要一个BinderProxy对象的IBinder接口来作为参数。因此,要获取Service Manager的Java远程接口ServiceManagerProxy,首先要有一个BinderProxy对象。下面将会看到这个BinderProxy对象是如何获得的。

再来看一下是通过什么路径来获取Service Manager的Java远程接口ServiceManagerProxy的。这个主角就是ServiceManager了,我们也先看一下ServiceManager是长什么样子的:


ServiceManager类有一个静态成员函数getIServiceManager,它的作用就是用来获取Service Manager的Java远程接口了,而这个函数又是通过ServiceManagerNative来获取Service Manager的Java远程接口的。

接下来,我们就看一下ServiceManager.getIServiceManager这个函数的实现,这个函数定义在frameworks/base/core/java/android/os/ServiceManager.java文件中:

view plain
  1. publicfinalclassServiceManager{
  2. ......
  3. privatestaticIServiceManagersServiceManager;
  4. ......
  5. privatestaticIServiceManagergetIServiceManager(){
  6. if(sServiceManager!=null){
  7. returnsServiceManager;
  8. }
  9. //Findtheservicemanager
  10. sServiceManager=ServiceManagerNative.asInterface(BinderInternal.getContextObject());
  11. returnsServiceManager;
  12. }
  13. ......
  14. }
如果其静态成员变量sServiceManager尚未创建,那么就调用ServiceManagerNative.asInterface函数来创建。在调用ServiceManagerNative.asInterface函数之前,首先要通过BinderInternal.getContextObject函数来获得一个BinderProxy对象。

我们来看一下BinderInternal.getContextObject的实现,这个函数定义在frameworks/base/core/java/com/android/internal/os/BinderInternal.java文件中:

view plain
  1. publicclassBinderInternal{
  2. ......
  3. /**
  4. *Returntheglobal"contextobject"ofthesystem.Thisisusually
  5. *animplementationofIServiceManager,whichyoucanusetofind
  6. *otherservices.
  7. */
  8. publicstaticfinalnativeIBindergetContextObject();
  9. ......
  10. }
这里可以看出,BinderInternal.getContextObject是一个JNI方法,它实现在frameworks/base/core/jni/android_util_Binder.cpp文件中:
view plain
  1. staticjobjectandroid_os_BinderInternal_getContextObject(JNIEnv*env,jobjectclazz)
  2. {
  3. sp<IBinder>b=ProcessState::self()->getContextObject(NULL);
  4. returnjavaObjectForIBinder(env,b);
  5. }
这里看到我们熟悉的ProcessState::self()->getContextObject函数,具体可以参考浅谈Android系统进程间通信(IPC)机制Binder中的Server和Client获得Service Manager接口之路一文。ProcessState::self()->getContextObject函数返回一个BpBinder对象,它的句柄值是0,即下面语句:
view plain
  1. sp<IBinder>b=ProcessState::self()->getContextObject(NULL);
相当于是:
view plain
  1. sp<IBinder>b=newBpBinder(0);
接着调用javaObjectForIBinder把这个BpBinder对象转换成一个BinderProxy对象:
view plain
  1. jobjectjavaObjectForIBinder(JNIEnv*env,constsp<IBinder>&val)
  2. {
  3. if(val==NULL)returnNULL;
  4. if(val->checkSubclass(&gBinderOffsets)){
  5. //Oneofourown!
  6. jobjectobject=static_cast<JavaBBinder*>(val.get())->object();
  7. //printf("objectForBinder%p:it'sourown%p!\n",val.get(),object);
  8. returnobject;
  9. }
  10. //Fortherestofthefunctionwewillholdthislock,toserialize
  11. //looking/creationofJavaproxiesfornativeBinderproxies.
  12. AutoMutex_l(mProxyLock);
  13. //Someoneelse's...doweknowaboutit?
  14. jobjectobject=(jobject)val->findObject(&gBinderProxyOffsets);
  15. if(object!=NULL){
  16. jobjectres=env->CallObjectMethod(object,gWeakReferenceOffsets.mGet);
  17. if(res!=NULL){
  18. LOGV("objectForBinder%p:foundexisting%p!\n",val.get(),res);
  19. returnres;
  20. }
  21. LOGV("Proxyobject%pofIBinder%pnolongerinworkingset!!!",object,val.get());
  22. android_atomic_dec(&gNumProxyRefs);
  23. val->detachObject(&gBinderProxyOffsets);
  24. env->DeleteGlobalRef(object);
  25. }
  26. object=env->NewObject(gBinderProxyOffsets.mClass,gBinderProxyOffsets.mConstructor);
  27. if(object!=NULL){
  28. LOGV("objectForBinder%p:creatednew%p!\n",val.get(),object);
  29. //Theproxyholdsareferencetothenativeobject.
  30. env->SetIntField(object,gBinderProxyOffsets.mObject,(int)val.get());
  31. val->incStrong(object);
  32. //Thenativeobjectneedstoholdaweakreferencebacktothe
  33. //proxy,sowecanretrievethesameproxyifitisstillactive.
  34. jobjectrefObject=env->NewGlobalRef(
  35. env->GetObjectField(object,gBinderProxyOffsets.mSelf));
  36. val->attachObject(&gBinderProxyOffsets,refObject,
  37. jnienv_to_javavm(env),proxy_cleanup);
  38. //Notethatanewobjectreferencehasbeencreated.
  39. android_atomic_inc(&gNumProxyRefs);
  40. incRefsCreated(env);
  41. }
  42. returnobject;
  43. }
在介绍这个函数之前,先来看两个变量gBinderOffsets和gBinderProxyOffsets的定义。

先看gBinderOffsets的定义:

view plain
  1. staticstructbindernative_offsets_t
  2. {
  3. //Classstate.
  4. jclassmClass;
  5. jmethodIDmExecTransact;
  6. //Objectstate.
  7. jfieldIDmObject;
  8. }gBinderOffsets;
简单来说,gBinderOffsets变量是用来记录上面第二个类图中的Binder类的相关信息的,它是在注册Binder类的JNI方法的int_register_android_os_Binder函数初始化的:
view plain
  1. constchar*constkBinderPathName="android/os/Binder";
  2. staticintint_register_android_os_Binder(JNIEnv*env)
  3. {
  4. jclassclazz;
  5. clazz=env->FindClass(kBinderPathName);
  6. LOG_FATAL_IF(clazz==NULL,"Unabletofindclassandroid.os.Binder");
  7. gBinderOffsets.mClass=(jclass)env->NewGlobalRef(clazz);
  8. gBinderOffsets.mExecTransact
  9. =env->GetMethodID(clazz,"execTransact","(IIII)Z");
  10. assert(gBinderOffsets.mExecTransact);
  11. gBinderOffsets.mObject
  12. =env->GetFieldID(clazz,"mObject","I");
  13. assert(gBinderOffsets.mObject);
  14. returnAndroidRuntime::registerNativeMethods(
  15. env,kBinderPathName,
  16. gBinderMethods,NELEM(gBinderMethods));
  17. }

再来看gBinderProxyOffsets的定义:

view plain
  1. staticstructbinderproxy_offsets_t
  2. {
  3. //Classstate.
  4. jclassmClass;
  5. jmethodIDmConstructor;
  6. jmethodIDmSendDeathNotice;
  7. //Objectstate.
  8. jfieldIDmObject;
  9. jfieldIDmSelf;
  10. }gBinderProxyOffsets;

简单来说,gBinderProxyOffsets是用来变量是用来记录上面第一个图中的BinderProxy类的相关信息的,它是在注册BinderProxy类的JNI方法的int_register_android_os_BinderProxy函数初始化的:

view plain
  1. constchar*constkBinderProxyPathName="android/os/BinderProxy";
  2. staticintint_register_android_os_BinderProxy(JNIEnv*env)
  3. {
  4. jclassclazz;
  5. clazz=env->FindClass("java/lang/ref/WeakReference");
  6. LOG_FATAL_IF(clazz==NULL,"Unabletofindclassjava.lang.ref.WeakReference");
  7. gWeakReferenceOffsets.mClass=(jclass)env->NewGlobalRef(clazz);
  8. gWeakReferenceOffsets.mGet
  9. =env->GetMethodID(clazz,"get","()Ljava/lang/Object;");
  10. assert(gWeakReferenceOffsets.mGet);
  11. clazz=env->FindClass("java/lang/Error");
  12. LOG_FATAL_IF(clazz==NULL,"Unabletofindclassjava.lang.Error");
  13. gErrorOffsets.mClass=(jclass)env->NewGlobalRef(clazz);
  14. clazz=env->FindClass(kBinderProxyPathName);
  15. LOG_FATAL_IF(clazz==NULL,"Unabletofindclassandroid.os.BinderProxy");
  16. gBinderProxyOffsets.mClass=(jclass)env->NewGlobalRef(clazz);
  17. gBinderProxyOffsets.mConstructor
  18. =env->GetMethodID(clazz,"<init>","()V");
  19. assert(gBinderProxyOffsets.mConstructor);
  20. gBinderProxyOffsets.mSendDeathNotice
  21. =env->GetStaticMethodID(clazz,"sendDeathNotice","(Landroid/os/IBinder$DeathRecipient;)V");
  22. assert(gBinderProxyOffsets.mSendDeathNotice);
  23. gBinderProxyOffsets.mObject
  24. =env->GetFieldID(clazz,"mObject","I");
  25. assert(gBinderProxyOffsets.mObject);
  26. gBinderProxyOffsets.mSelf
  27. =env->GetFieldID(clazz,"mSelf","Ljava/lang/ref/WeakReference;");
  28. assert(gBinderProxyOffsets.mSelf);
  29. returnAndroidRuntime::registerNativeMethods(
  30. env,kBinderProxyPathName,
  31. gBinderProxyMethods,NELEM(gBinderProxyMethods));
  32. }
回到前面的javaObjectForIBinder函数中,下面这段代码:
view plain
  1. if(val->checkSubclass(&gBinderOffsets)){
  2. //Oneofourown!
  3. jobjectobject=static_cast<JavaBBinder*>(val.get())->object();
  4. //printf("objectForBinder%p:it'sourown%p!\n",val.get(),object);
  5. returnobject;
  6. }
前面说过,这里传进来的参数是一个BpBinder的指针,而BpBinder::checkSubclass继承于父类IBinder::checkSubclass,它什么也不做就返回false。

于是函数继续往下执行:

view plain
  1. jobjectobject=(jobject)val->findObject(&gBinderProxyOffsets);
由于这个BpBinder对象是第一创建,它里面什么对象也没有,因此,这里返回的object为NULL。

于是函数又继续往下执行:

view plain
  1. object=env->NewObject(gBinderProxyOffsets.mClass,gBinderProxyOffsets.mConstructor);
这里,就创建了一个BinderProxy对象了。创建了之后,要把这个BpBinder对象和这个BinderProxy对象关联起来:

view plain
  1. env->SetIntField(object,gBinderProxyOffsets.mObject,(int)val.get());
就是通过BinderProxy.mObject成员变量来关联的了,BinderProxy.mObject成员变量记录了这个BpBinder对象的地址。

接下去,还要把它放到BpBinder里面去,下次就要使用时,就可以在上一步调用BpBinder::findObj把它找回来了:

view plain
  1. val->attachObject(&gBinderProxyOffsets,refObject,
  2. jnienv_to_javavm(env),proxy_cleanup);
最后,就把这个BinderProxy返回到android_os_BinderInternal_getContextObject函数,最终返回到最开始的ServiceManager.getIServiceManager函数中来了,于是,我们就获得一个BinderProxy对象了。

回到ServiceManager.getIServiceManager中,从下面语句返回:

view plain
  1. sServiceManager=ServiceManagerNative.asInterface(BinderInternal.getContextObject());

相当于是:

view plain
  1. sServiceManager=ServiceManagerNative.asInterface(newBinderProxy());

接下去就是调用ServiceManagerNative.asInterface函数了,这个函数定义在frameworks/base/core/java/android/os/ServiceManagerNative.java文件中:

view plain
  1. publicabstractclassServiceManagerNative......
  2. {
  3. ......
  4. staticpublicIServiceManagerasInterface(IBinderobj)
  5. {
  6. if(obj==null){
  7. returnnull;
  8. }
  9. IServiceManagerin=
  10. (IServiceManager)obj.queryLocalInterface(descriptor);
  11. if(in!=null){
  12. returnin;
  13. }
  14. returnnewServiceManagerProxy(obj);
  15. }
  16. ......
  17. }
这里的参数obj是一个BinderProxy对象,它的queryLocalInterface函数返回null。因此,最终以这个BinderProxy对象为参数创建一个ServiceManagerProxy对象。

返回到ServiceManager.getIServiceManager中,从下面语句返回:

view plain
  1. sServiceManager=ServiceManagerNative.asInterface(newBinderProxy());

就相当于是:

view plain
  1. sServiceManager=newServiceManagerProxy(newBinderProxy());
于是,我们的目标终于完成了。

总结一下,就是在Java层,我们拥有了一个Service Manager远程接口ServiceManagerProxy,而这个ServiceManagerProxy对象在JNI层有一个句柄值为0的BpBinder对象与之通过gBinderProxyOffsets关联起来。

这样获取Service Manager的Java远程接口的过程就完成了。

二.HelloService接口的定义

前面我们在学习Android系统的硬件抽象层(HAL)时,在在Ubuntu上为Android系统的Application Frameworks层增加硬件访问服务这篇文章中,我们编写了一个硬件服务HelloService,它的服务接口定义在frameworks/base/core/java/android/os/IHelloService.aidl文件中:

view plain
  1. packageandroid.os;
  2. interfaceIHelloService
  3. {
  4. voidsetVal(intval);
  5. intgetVal();
  6. }

这个服务接口很简单,只有两个函数,分别用来读写硬件寄存器。

注意,这是一个aidl文件,编译后会生成一个IHelloService.java。我们来看一下这个文件的内容隐藏着什么奥秘,可以这么神奇地支持进程间通信。

view plain
  1. /*
  2. *Thisfileisauto-generated.DONOTMODIFY.
  3. *Originalfile:frameworks/base/core/java/android/os/IHelloService.aidl
  4. */
  5. packageandroid.os;
  6. publicinterfaceIHelloServiceextendsandroid.os.IInterface
  7. {
  8. /**Local-sideIPCimplementationstubclass.*/
  9. publicstaticabstractclassStubextendsandroid.os.Binderimplementsandroid.os.IHelloService
  10. {
  11. privatestaticfinaljava.lang.StringDESCRIPTOR="android.os.IHelloService";
  12. /**Constructthestubatattachittotheinterface.*/
  13. publicStub()
  14. {
  15. this.attachInterface(this,DESCRIPTOR);
  16. }
  17. /**
  18. *CastanIBinderobjectintoanandroid.os.IHelloServiceinterface,
  19. *generatingaproxyifneeded.
  20. */
  21. publicstaticandroid.os.IHelloServiceasInterface(android.os.IBinderobj)
  22. {
  23. if((obj==null)){
  24. returnnull;
  25. }
  26. android.os.IInterfaceiin=(android.os.IInterface)obj.queryLocalInterface(DESCRIPTOR);
  27. if(((iin!=null)&&(iininstanceofandroid.os.IHelloService))){
  28. return((android.os.IHelloService)iin);
  29. }
  30. returnnewandroid.os.IHelloService.Stub.Proxy(obj);
  31. }
  32. publicandroid.os.IBinderasBinder()
  33. {
  34. returnthis;
  35. }
  36. @Override
  37. publicbooleanonTransact(intcode,android.os.Parceldata,android.os.Parcelreply,intflags)throwsandroid.os.RemoteException
  38. {
  39. switch(code)
  40. {
  41. caseINTERFACE_TRANSACTION:
  42. {
  43. reply.writeString(DESCRIPTOR);
  44. returntrue;
  45. }
  46. caseTRANSACTION_setVal:
  47. {
  48. data.enforceInterface(DESCRIPTOR);
  49. int_arg0;
  50. _arg0=data.readInt();
  51. this.setVal(_arg0);
  52. reply.writeNoException();
  53. returntrue;
  54. }
  55. caseTRANSACTION_getVal:
  56. {
  57. data.enforceInterface(DESCRIPTOR);
  58. int_result=this.getVal();
  59. reply.writeNoException();
  60. reply.writeInt(_result);
  61. returntrue;
  62. }
  63. }
  64. returnsuper.onTransact(code,data,reply,flags);
  65. }
  66. privatestaticclassProxyimplementsandroid.os.IHelloService
  67. {
  68. privateandroid.os.IBindermRemote;
  69. Proxy(android.os.IBinderremote)
  70. {
  71. mRemote=remote;
  72. }
  73. publicandroid.os.IBinderasBinder()
  74. {
  75. returnmRemote;
  76. }
  77. publicjava.lang.StringgetInterfaceDescriptor()
  78. {
  79. returnDESCRIPTOR;
  80. }
  81. publicvoidsetVal(intval)throwsandroid.os.RemoteException
  82. {
  83. android.os.Parcel_data=android.os.Parcel.obtain();
  84. android.os.Parcel_reply=android.os.Parcel.obtain();
  85. try{
  86. _data.writeInterfaceToken(DESCRIPTOR);
  87. _data.writeInt(val);
  88. mRemote.transact(Stub.TRANSACTION_setVal,_data,_reply,0);
  89. _reply.readException();
  90. }
  91. finally{
  92. _reply.recycle();
  93. _data.recycle();
  94. }
  95. }
  96. publicintgetVal()throwsandroid.os.RemoteException
  97. {
  98. android.os.Parcel_data=android.os.Parcel.obtain();
  99. android.os.Parcel_reply=android.os.Parcel.obtain();
  100. int_result;
  101. try{
  102. _data.writeInterfaceToken(DESCRIPTOR);
  103. mRemote.transact(Stub.TRANSACTION_getVal,_data,_reply,0);
  104. _reply.readException();
  105. _result=_reply.readInt();
  106. }
  107. finally{
  108. _reply.recycle();
  109. _data.recycle();
  110. }
  111. return_result;
  112. }
  113. }
  114. staticfinalintTRANSACTION_setVal=(android.os.IBinder.FIRST_CALL_TRANSACTION+0);
  115. staticfinalintTRANSACTION_getVal=(android.os.IBinder.FIRST_CALL_TRANSACTION+1);
  116. }
  117. publicvoidsetVal(intval)throwsandroid.os.RemoteException;
  118. publicintgetVal()throwsandroid.os.RemoteException;
  119. }

这里我们可以看到IHelloService.aidl这个文件编译后的真面目,原来就是根据IHelloService接口的定义生成相应的Stub和Proxy类,这个就是我们熟悉的Binder机制的内容了,即实现这个HelloService的Server必须继续于这里的IHelloService.Stub类,而这个HelloService的远程接口就是这里的IHelloService.Stub.Proxy对象获得的IHelloService接口。接下来的内容,我们就可以看到IHelloService.Stub和IHelloService.Stub.Proxy是怎么创建或者使用的。

三.HelloService的启动过程

在讨论HelloService的启动过程之前,我们先来看一下实现HelloService接口的Server是怎么定义的。

回忆在Ubuntu上为Android系统的Application Frameworks层增加硬件访问服务一文,我们在frameworks/base/services/java/com/android/server目录下新增了一个HelloService.java文件:

view plain
  1. packagecom.android.server;
  2. importandroid.content.Context;
  3. importandroid.os.IHelloService;
  4. importandroid.util.Slog;
  5. publicclassHelloServiceextendsIHelloService.Stub{
  6. privatestaticfinalStringTAG="HelloService";
  7. HelloService(){
  8. init_native();
  9. }
  10. publicvoidsetVal(intval){
  11. setVal_native(val);
  12. }
  13. publicintgetVal(){
  14. returngetVal_native();
  15. }
  16. privatestaticnativebooleaninit_native();
  17. privatestaticnativevoidsetVal_native(intval);
  18. privatestaticnativeintgetVal_native();
  19. }

这里,我们可以看到,HelloService继续了IHelloService.Stub类,它通过本地方法调用实现了getVal和setVal两个函数。我们不关心这两个函数的具体实现,有兴趣的读者可以参考在Ubuntu上为Android系统的Application Frameworks层增加硬件访问服务一文。
有了HelloService这个Server类后,下一步就是考虑怎么样把它启动起来了。在frameworks/base/services/java/com/android/server/SystemServer.java文件中,定义了SystemServer类。SystemServer对象是在系统启动的时候创建的,它被创建的时候会启动一个线程来创建HelloService,并且把它添加到Service Manager中去。

我们来看一下这部份的代码:

view plain
  1. classServerThreadextendsThread{
  2. ......
  3. @Override
  4. publicvoidrun(){
  5. ......
  6. Looper.prepare();
  7. ......
  8. try{
  9. Slog.i(TAG,"HelloService");
  10. ServiceManager.addService("hello",newHelloService());
  11. }catch(Throwablee){
  12. Slog.e(TAG,"FailurestartingHelloService",e);
  13. }
  14. ......
  15. Looper.loop();
  16. ......
  17. }
  18. }
  19. ......
  20. publicclassSystemServer
  21. {
  22. ......
  23. /**
  24. *ThismethodiscalledfromZygotetoinitializethesystem.Thiswillcausethenative
  25. *services(SurfaceFlinger,AudioFlinger,etc..)tobestarted.Afterthatitwillcallback
  26. *upintoinit2()tostarttheAndroidservices.
  27. */
  28. nativepublicstaticvoidinit1(String[]args);
  29. ......
  30. publicstaticfinalvoidinit2(){
  31. Slog.i(TAG,"EnteredtheAndroidsystemserver!");
  32. Threadthr=newServerThread();
  33. thr.setName("android.server.ServerThread");
  34. thr.start();
  35. }
  36. ......
  37. }

这里,我们可以看到,在ServerThread.run函数中,执行了下面代码把HelloService添加到Service Manager中去。这里我们关注把HelloService添加到Service Manager中去的代码:

view plain
  1. try{
  2. Slog.i(TAG,"HelloService");
  3. ServiceManager.addService("hello",newHelloService());
  4. }catch(Throwablee){
  5. Slog.e(TAG,"FailurestartingHelloService",e);
  6. }

通过调用ServiceManager.addService把一个HelloService实例添加到Service Manager中去。

我们先来看一下HelloService的创建过程:

view plain
  1. newHelloService();

这个语句会调用HelloService类的构造函数,而HelloService类继承于IHelloService.Stub类,IHelloService.Stub类又继承了Binder类,因此,最后会调用Binder类的构造函数:

view plain
  1. publicclassBinderimplementsIBinder{
  2. ......
  3. privateintmObject;
  4. ......
  5. publicBinder(){
  6. init();
  7. ......
  8. }
  9. privatenativefinalvoidinit();
  10. ......
  11. }

这里调用了一个JNI方法init来初始化这个Binder对象,这个JNI方法定义在frameworks/base/core/jni/android_util_Binder.cpp文件中:

view plain
  1. staticvoidandroid_os_Binder_init(JNIEnv*env,jobjectclazz)
  2. {
  3. JavaBBinderHolder*jbh=newJavaBBinderHolder(env,clazz);
  4. if(jbh==NULL){
  5. jniThrowException(env,"java/lang/OutOfMemoryError",NULL);
  6. return;
  7. }
  8. LOGV("JavaBinder%p:acquiringfirstrefonholder%p",clazz,jbh);
  9. jbh->incStrong(clazz);
  10. env->SetIntField(clazz,gBinderOffsets.mObject,(int)jbh);
  11. }
它实际上只做了一件事情,就是创建一个JavaBBinderHolder对象jbh,然后把这个对象的地址保存在上面的Binder类的mObject成员变量中,后面我们会用到。

回到ServerThread.run函数中,我们再来看一下ServiceManager.addService函数的实现:

view plain
  1. publicfinalclassServiceManager{
  2. ......
  3. privatestaticIServiceManagersServiceManager;
  4. ......
  5. publicstaticvoidaddService(Stringname,IBinderservice){
  6. try{
  7. getIServiceManager().addService(name,service);
  8. }catch(RemoteExceptione){
  9. Log.e(TAG,"errorinaddService",e);
  10. }
  11. }
  12. ......
  13. }

这里的getIServiceManager函数我们在前面已经分析过了,它返回的是一个ServiceManagerProxy对象的IServiceManager接口。因此,我们进入到ServiceManagerProxy.addService中去看看:

view plain
  1. classServiceManagerProxyimplementsIServiceManager{
  2. publicServiceManagerProxy(IBinderremote){
  3. mRemote=remote;
  4. }
  5. ......
  6. publicvoidaddService(Stringname,IBinderservice)
  7. throwsRemoteException{
  8. Parceldata=Parcel.obtain();
  9. Parcelreply=Parcel.obtain();
  10. data.writeInterfaceToken(IServiceManager.descriptor);
  11. data.writeString(name);
  12. data.writeStrongBinder(service);
  13. mRemote.transact(ADD_SERVICE_TRANSACTION,data,reply,0);
  14. reply.recycle();
  15. data.recycle();
  16. }
  17. ......
  18. privateIBindermRemote;
  19. }

这里的Parcel类是用Java来实现的,它跟我们前面几篇文章介绍Binder机制时提到的用C++实现的Parcel类的作用是一样的,即用来在两个进程之间传递数据。

这里我们关注是如何把参数service写到data这个Parcel对象中去的:

view plain
  1. data.writeStrongBinder(service);

我们来看看Parcel.writeStrongBinder函数的实现:

view plain
  1. publicfinalclassParcel{
  2. ......
  3. /**
  4. *WriteanobjectintotheparcelatthecurrentdataPosition(),
  5. *growingdataCapacity()ifneeded.
  6. */
  7. publicfinalnativevoidwriteStrongBinder(IBinderval);
  8. ......
  9. }

这里的writeStrongBinder函数又是一个JNI方法,它定义在frameworks/base/core/jni/android_util_Binder.cpp文件中:

view plain
  1. staticvoidandroid_os_Parcel_writeStrongBinder(JNIEnv*env,jobjectclazz,jobjectobject)
  2. {
  3. Parcel*parcel=parcelForJavaObject(env,clazz);
  4. if(parcel!=NULL){
  5. conststatus_terr=parcel->writeStrongBinder(ibinderForJavaObject(env,object));
  6. if(err!=NO_ERROR){
  7. jniThrowException(env,"java/lang/OutOfMemoryError",NULL);
  8. }
  9. }
  10. }
这里的clazz参数是一个Java语言实现的Parcel对象,通过parcelForJavaObject把它转换成C++语言实现的Parcel对象。这个函数的实现我们就不看了,有兴趣的读者可以研究一下,这个函数也是实现在frameworks/base/core/jni/android_util_Binder.cpp这个文件中。
这里的object参数是一个Java语言实现的Binder对象,在调用C++语言实现的Parcel::writeStrongBinder把这个对象写入到parcel对象时,首先通过ibinderForJavaObject函数把这个Java语言实现的Binder对象转换为C++语言实现的JavaBBinderHolder对象:
view plain
  1. sp<IBinder>ibinderForJavaObject(JNIEnv*env,jobjectobj)
  2. {
  3. if(obj==NULL)returnNULL;
  4. if(env->IsInstanceOf(obj,gBinderOffsets.mClass)){
  5. JavaBBinderHolder*jbh=(JavaBBinderHolder*)
  6. env->GetIntField(obj,gBinderOffsets.mObject);
  7. returnjbh!=NULL?jbh->get(env):NULL;
  8. }
  9. if(env->IsInstanceOf(obj,gBinderProxyOffsets.mClass)){
  10. return(IBinder*)
  11. env->GetIntField(obj,gBinderProxyOffsets.mObject);
  12. }
  13. LOGW("ibinderForJavaObject:%pisnotaBinderobject",obj);
  14. returnNULL;
  15. }

我们知道,这里的obj参数是一个Binder类的实例,因此,这里会进入到第一个if语句中去。

在前面创建HelloService对象,曾经在调用到HelloService的父类Binder中,曾经在JNI层创建了一个JavaBBinderHolder对象,然后把这个对象的地址保存在Binder类的mObject成员变量中,因此,这里把obj对象的mObject成员变量强制转为JavaBBinderHolder对象。

到了这里,这个函数的功课还未完成,还剩下最后关键的一步:

view plain
  1. returnjbh!=NULL?jbh->get(env):NULL;

这里就是jbh->get这个语句了。

在JavaBBinderHolder类中,有一个成员变量mBinder,它的类型为JavaBBinder,而JavaBBinder类继承于BBinder类。在前面学习Binder机制的C++语言实现时,我们在Android系统进程间通信(IPC)机制Binder中的Server启动过程源代码分析这篇文章中,曾经介绍过,IPCThreadState类负责与Binder驱动程序进行交互,它把从Binder驱动程序读出来的请求作简单的处理后,最后把这个请求扔给BBinder的onTransact函数来进一步处理。

这里,我们就是要把JavaBBinderHolder里面的JavaBBinder类型Binder实体添加到Service Manager中去,以便使得这个HelloService有Client来请求服务时,由Binder驱动程序来唤醒这个Server线程,进而调用这个JavaBBinder类型Binder实体的onTransact函数来进一步处理,这个函数我们在后面会继续介绍。

先来看一下JavaBBinderHolder::get函数的实现:

view plain
  1. classJavaBBinderHolder:publicRefBase
  2. {
  3. ......
  4. JavaBBinderHolder(JNIEnv*env,jobjectobject)
  5. :mObject(object)
  6. {
  7. ......
  8. }
  9. ......
  10. sp<JavaBBinder>get(JNIEnv*env)
  11. {
  12. AutoMutex_l(mLock);
  13. sp<JavaBBinder>b=mBinder.promote();
  14. if(b==NULL){
  15. b=newJavaBBinder(env,mObject);
  16. mBinder=b;
  17. ......
  18. }
  19. returnb;
  20. }
  21. ......
  22. jobjectmObject;
  23. wp<JavaBBinder>mBinder;
  24. };

这里是第一次调用get函数,因此,会创建一个JavaBBinder对象,并且保存在mBinder成员变量中。注意,这里的mObject就是上面创建的HelloService对象了,这是一个Java对象。这个HelloService对象最终也会保存在JavaBBinder对象的成员变量mObject中。

回到android_os_Parcel_writeStrongBinder函数中,下面这个语句:

view plain
  1. conststatus_terr=parcel->writeStrongBinder(ibinderForJavaObject(env,object));
相当于是:
view plain
  1. conststatus_terr=parcel->writeStrongBinder((JavaBBinderHodler*)(obj.mObject));
因此,这里的效果相当于是写入了一个JavaBBinder类型的Binder实体到parcel中去。这与我们前面介绍的Binder机制的C++实现是一致的。

接着,再回到ServiceManagerProxy.addService这个函数中,最后它通过其成员变量mRemote来执行进程间通信操作。前面我们在介绍如何获取Service Manager远程接口时提到,这里的mRemote成员变量实际上是一个BinderProxy对象,因此,我们再来看看BinderProxy.transact函数的实现:

view plain
  1. finalclassBinderProxyimplementsIBinder{
  2. ......
  3. publicnativebooleantransact(intcode,Parceldata,Parcelreply,
  4. intflags)throwsRemoteException;
  5. ......
  6. }

这里的transact成员函数又是一个JNI方法,它定义在frameworks/base/core/jni/android_util_Binder.cpp文件中:

view plain
  1. staticjbooleanandroid_os_BinderProxy_transact(JNIEnv*env,jobjectobj,
  2. jintcode,jobjectdataObj,
  3. jobjectreplyObj,jintflags)
  4. {
  5. ......
  6. Parcel*data=parcelForJavaObject(env,dataObj);
  7. if(data==NULL){
  8. returnJNI_FALSE;
  9. }
  10. Parcel*reply=parcelForJavaObject(env,replyObj);
  11. if(reply==NULL&&replyObj!=NULL){
  12. returnJNI_FALSE;
  13. }
  14. IBinder*target=(IBinder*)
  15. env->GetIntField(obj,gBinderProxyOffsets.mObject);
  16. if(target==NULL){
  17. jniThrowException(env,"java/lang/IllegalStateException","Binderhasbeenfinalized!");
  18. returnJNI_FALSE;
  19. }
  20. ......
  21. status_terr=target->transact(code,*data,reply,flags);
  22. ......
  23. if(err==NO_ERROR){
  24. returnJNI_TRUE;
  25. }elseif(err==UNKNOWN_TRANSACTION){
  26. returnJNI_FALSE;
  27. }
  28. signalExceptionForError(env,obj,err);
  29. returnJNI_FALSE;
  30. }

这里传进来的参数dataObj和replyObj是一个Java接口实现的Parcel类,由于这里是JNI层,需要把它转换为C++实现的Parcel类,它们就是通过我们前面说的parcelForJavaObject函数进行转换的。

前面我们在分析如何获取Service Manager远程接口时,曾经说到,在JNI层中,创建了一个BpBinder对象,它的句柄值为0,它的地址保存在gBinderProxyOffsets.mObject中,因此,这里通过下面语句得到这个BpBinder对象的IBinder接口:

view plain
  1. IBinder*target=(IBinder*)
  2. env->GetIntField(obj,gBinderProxyOffsets.mObject);

有了这个IBinder接口后,就和我们前面几篇文章介绍Binder机制的C/C++实现一致了。

最后,通过BpBinder::transact函数进入到Binder驱动程序,然后Binder驱动程序唤醒Service Manager响应这个ADD_SERVICE_TRANSACTION请求:

view plain
  1. status_terr=target->transact(code,*data,reply,flags);

具体可以参考Android系统进程间通信(IPC)机制Binder中的Server启动过程源代码分析一文。需要注意的是,这里的data包含了一个JavaBBinderHolder类型的Binder实体对象,它就代表了我们上面创建的HelloService。Service Manager收到这个ADD_SERVICE_TRANSACTION请求时,就会把这个Binder实体纳入到自己内部进行管理。
这样,实现HelloService的Server的启动过程就完成了。

四.Client获取HelloService的Java远程接口的过程

前面我们在学习Android系统硬件抽象层(HAL)时,在在Ubuntu上为Android系统内置Java应用程序测试Application Frameworks层的硬件服务这篇文章中,我们创建了一个应用程序,这个应用程序作为一个Client角色,借助Service Manager这个Java远程接口来获得HelloService的远程接口,进而调用HelloService提供的服务。

我们看看它是如何借助Service Manager这个Java远程接口来获得HelloService的远程接口的。在Hello这个Activity的onCreate函数,通过IServiceManager.getService函数来获得HelloService的远程接口:

view plain
  1. publicclassHelloextendsActivityimplementsOnClickListener{
  2. ......
  3. privateIHelloServicehelloService=null;
  4. ......
  5. @Override
  6. publicvoidonCreate(BundlesavedInstanceState){
  7. helloService=IHelloService.Stub.asInterface(
  8. ServiceManager.getService("hello"));
  9. }
  10. ......
  11. }

我们先来看ServiceManager.getService的实现。前面我们说过,这里实际上是调用了ServiceManagerProxy.getService函数:

view plain
  1. classServiceManagerProxyimplementsIServiceManager{
  2. publicServiceManagerProxy(IBinderremote){
  3. mRemote=remote;
  4. }
  5. ......
  6. publicIBindergetService(Stringname)throwsRemoteException{
  7. Parceldata=Parcel.obtain();
  8. Parcelreply=Parcel.obtain();
  9. data.writeInterfaceToken(IServiceManager.descriptor);
  10. data.writeString(name);
  11. mRemote.transact(GET_SERVICE_TRANSACTION,data,reply,0);
  12. IBinderbinder=reply.readStrongBinder();
  13. reply.recycle();
  14. data.recycle();
  15. returnbinder;
  16. }
  17. ......
  18. privateIBindermRemote;
  19. }

最终通过mRemote.transact来执行实际操作。我们在前面已经介绍过了,这里的mRemote实际上是一个BinderProxy对象,它的transact成员函数是一个JNI方法,实现在frameworks/base/core/jni/android_util_Binder.cpp文件中的android_os_BinderProxy_transact函数中。

这个函数前面我们已经看到了,这里就不再列出来了。不过,当这个函数从:

view plain
  1. status_terr=target->transact(code,*data,reply,flags);

这里的reply变量里面就包括了一个HelloService的引用了。注意,这里的reply变量就是我们在ServiceManagerProxy.getService函数里面传进来的参数reply,它是一个Parcel对象。

回到ServiceManagerProxy.getService函数中,从下面语句返回:

view plain
  1. mRemote.transact(GET_SERVICE_TRANSACTION,data,reply,0);

接着,就通过下面语句将这个HelloService的引用读出来:

view plain
  1. IBinderbinder=reply.readStrongBinder();

我们看看Parcel.readStrongBinder的实现:

view plain
  1. publicfinalclassParcel{
  2. ......
  3. /**
  4. *ReadanobjectfromtheparcelatthecurrentdataPosition().
  5. */
  6. publicfinalnativeIBinderreadStrongBinder();
  7. ......
  8. }

它也是一个JNI方法,实现在frameworks/base/core/jni/android_util_Binder.cpp文件中:

view plain
  1. staticjobjectandroid_os_Parcel_readStrongBinder(JNIEnv*env,jobjectclazz)
  2. {
  3. Parcel*parcel=parcelForJavaObject(env,clazz);
  4. if(parcel!=NULL){
  5. returnjavaObjectForIBinder(env,parcel->readStrongBinder());
  6. }
  7. returnNULL;
  8. }

这里首先把Java语言实现的Parcel对象class转换成C++语言实现的Parcel对象parcel,接着,通过parcel->readStrongBinder函数来获得一个Binder引用。

我们在前面学习Binder机制时,在Android系统进程间通信(IPC)机制Binder中的Client获得Server远程接口过程源代码分析这篇文章中,曾经分析过这个函数,它最终返回来的是一个BpBinder对象,因此,下面的语句:

view plain
  1. returnjavaObjectForIBinder(env,parcel->readStrongBinder());

就相当于是:

view plain
  1. returnjavaObjectForIBinder(env,newBpBinder(handle));

这里的handle就是HelloService这个Binder实体在Client进程中的句柄了,它是由Binder驱动程序设置的,上层不用关心它的值具体是多少。至于javaObjectForIBinder这个函数,我们前面介绍如何获取Service Manager的Java远程接口时已经有详细介绍,这里就不累述了,它的作用就是创建一个BinderProxy对象,并且把刚才获得的BpBinder对象的地址保存在这个BinderProxy对象的mObject成员变量中。

最后返回到Hello.onCreate函数中,从下面语句返回:

view plain
  1. helloService=IHelloService.Stub.asInterface(
  2. ServiceManager.getService("hello"));

就相当于是:

view plain
  1. helloService=IHelloService.Stub.asInterface(newBinderProxy()));

回忆一下前面介绍IHelloService接口的定义时,IHelloService.Stub.asInterface是这样定义的:

view plain
  1. publicinterfaceIHelloServiceextendsandroid.os.IInterface
  2. {
  3. /**Local-sideIPCimplementationstubclass.*/
  4. publicstaticabstractclassStubextendsandroid.os.Binderimplementsandroid.os.IHelloService
  5. {
  6. ......
  7. publicstaticandroid.os.IHelloServiceasInterface(android.os.IBinderobj)
  8. {
  9. if((obj==null)){
  10. returnnull;
  11. }
  12. android.os.IInterfaceiin=(android.os.IInterface)obj.queryLocalInterface(DESCRIPTOR);
  13. if(((iin!=null)&&(iininstanceofandroid.os.IHelloService))){
  14. return((android.os.IHelloService)iin);
  15. }
  16. returnnewandroid.os.IHelloService.Stub.Proxy(obj);
  17. }
  18. ......
  19. }
  20. }

这里的obj是一个BinderProxy对象,它的queryLocalInterface返回null,于是调用下面语句获得HelloService的远程接口:

view plain
  1. returnnewandroid.os.IHelloService.Stub.Proxy(obj);

相当于是:

view plain
  1. returnnewandroid.os.IHelloService.Stub.Proxy(newBinderProxy());

这样,我们就获得了HelloService的远程接口了,它实质上是一个实现了IHelloService接口的IHelloService.Stub.Proxy对象。

五.Client通过HelloService的Java远程接口来使用HelloService提供的服务的过程

上面介绍的Hello这个Activity获得了HelloService的远程接口后,就可以使用它的服务了。

我们以使用IHelloService.getVal函数为例详细说明。在Hello::onClick函数中调用了IHelloService.getVal函数:

view plain
  1. publicclassHelloextendsActivityimplementsOnClickListener{
  2. ......
  3. @Override
  4. publicvoidonClick(Viewv){
  5. if(v.equals(readButton)){
  6. intval=helloService.getVal();
  7. ......
  8. }
  9. elseif(v.equals(writeButton)){
  10. ......
  11. }
  12. elseif(v.equals(clearButton)){
  13. ......
  14. }
  15. }
  16. ......
  17. }

通知前面的分析,我们知道,这里的helloService接口实际上是一个IHelloService.Stub.Proxy对象,因此,我们进入到IHelloService.Stub.Proxy类的getVal函数中:

view plain
  1. publicinterfaceIHelloServiceextendsandroid.os.IInterface
  2. {
  3. /**Local-sideIPCimplementationstubclass.*/
  4. publicstaticabstractclassStubextendsandroid.os.Binderimplementsandroid.os.IHelloService
  5. {
  6. ......
  7. privatestaticclassProxyimplementsandroid.os.IHelloService
  8. {
  9. privateandroid.os.IBindermRemote;
  10. ......
  11. publicintgetVal()throwsandroid.os.RemoteException
  12. {
  13. android.os.Parcel_data=android.os.Parcel.obtain();
  14. android.os.Parcel_reply=android.os.Parcel.obtain();
  15. int_result;
  16. try{
  17. _data.writeInterfaceToken(DESCRIPTOR);
  18. mRemote.transact(Stub.TRANSACTION_getVal,_data,_reply,0);
  19. _reply.readException();
  20. _result=_reply.readInt();
  21. }
  22. finally{
  23. _reply.recycle();
  24. _data.recycle();
  25. }
  26. return_result;
  27. }
  28. }
  29. ......
  30. staticfinalintTRANSACTION_getVal=(android.os.IBinder.FIRST_CALL_TRANSACTION+1);
  31. }
  32. ......
  33. }

这里我们可以看出,实际上是通过mRemote.transact来请求HelloService执行TRANSACTION_getVal操作。这里的mRemote是一个BinderProxy对象,这是我们在前面获取HelloService的Java远程接口的过程中创建的。

BinderProxy.transact函数是一个JNI方法,我们在前面已经介绍过了,这里不再累述。最过调用到Binder驱动程序,Binder驱动程序唤醒HelloService这个Server。前面我们在介绍HelloService的启动过程时,曾经提到,HelloService这个Server线程被唤醒之后,就会调用JavaBBinder类的onTransact函数:

view plain
  1. classJavaBBinder:publicBBinder
  2. {
  3. JavaBBinder(JNIEnv*env,jobjectobject)
  4. :mVM(jnienv_to_javavm(env)),mObject(env->NewGlobalRef(object))
  5. {
  6. ......
  7. }
  8. ......
  9. virtualstatus_tonTransact(
  10. uint32_tcode,constParcel&data,Parcel*reply,uint32_tflags=0)
  11. {
  12. JNIEnv*env=javavm_to_jnienv(mVM);
  13. ......
  14. jbooleanres=env->CallBooleanMethod(mObject,gBinderOffsets.mExecTransact,
  15. code,(int32_t)&data,(int32_t)reply,flags);
  16. ......
  17. returnres!=JNI_FALSE?NO_ERROR:UNKNOWN_TRANSACTION;
  18. }
  19. ......
  20. JavaVM*constmVM;
  21. jobjectconstmObject;
  22. };

前面我们在介绍HelloService的启动过程时,曾经介绍过,JavaBBinder类里面的成员变量mObject就是HelloService类的一个实例对象了。因此,这里通过语句:

view plain
  1. jbooleanres=env->CallBooleanMethod(mObject,gBinderOffsets.mExecTransact,
  2. code,(int32_t)&data,(int32_t)reply,flags);

就调用了HelloService.execTransact函数,而HelloService.execTransact函数继承了Binder类的execTransact函数:

view plain
  1. publicclassBinderimplementsIBinder{
  2. ......
  3. //Entrypointfromandroid_util_Binder.cpp'sonTransact
  4. privatebooleanexecTransact(intcode,intdataObj,intreplyObj,intflags){
  5. Parceldata=Parcel.obtain(dataObj);
  6. Parcelreply=Parcel.obtain(replyObj);
  7. //theoretically,weshouldcalltransact,whichwillcallonTransact,
  8. //butallthatdoesisrewindit,andwejustgotthesefromanIPC,
  9. //sowe'lljustcallitdirectly.
  10. booleanres;
  11. try{
  12. res=onTransact(code,data,reply,flags);
  13. }catch(RemoteExceptione){
  14. reply.writeException(e);
  15. res=true;
  16. }catch(RuntimeExceptione){
  17. reply.writeException(e);
  18. res=true;
  19. }catch(OutOfMemoryErrore){
  20. RuntimeExceptionre=newRuntimeException("Outofmemory",e);
  21. reply.writeException(re);
  22. res=true;
  23. }
  24. reply.recycle();
  25. data.recycle();
  26. returnres;
  27. }
  28. }

这里又调用了onTransact函数来作进一步处理。由于HelloService类继承了IHelloService.Stub类,而IHelloService.Stub类实现了onTransact函数,HelloService类没有实现,因此,最终调用了IHelloService.Stub.onTransact函数:

view plain
  1. publicinterfaceIHelloServiceextendsandroid.os.IInterface
  2. {
  3. /**Local-sideIPCimplementationstubclass.*/
  4. publicstaticabstractclassStubextendsandroid.os.Binderimplementsandroid.os.IHelloService
  5. {
  6. ......
  7. @Override
  8. publicbooleanonTransact(intcode,android.os.Parceldata,android.os.Parcelreply,intflags)throwsandroid.os.RemoteException
  9. {
  10. switch(code)
  11. {
  12. ......
  13. caseTRANSACTION_getVal:
  14. {
  15. data.enforceInterface(DESCRIPTOR);
  16. int_result=this.getVal();
  17. reply.writeNoException();
  18. reply.writeInt(_result);
  19. returntrue;
  20. }
  21. }
  22. returnsuper.onTransact(code,data,reply,flags);
  23. }
  24. ......
  25. }
  26. }

函数最终又调用了HelloService.getVal函数:

view plain
  1. publicclassHelloServiceextendsIHelloService.Stub{
  2. ......
  3. publicintgetVal(){
  4. returngetVal_native();
  5. }
  6. ......
  7. privatestaticnativeintgetVal_native();
  8. }

最终,经过层层返回,就回到IHelloService.Stub.Proxy.getVal函数中来了,从下面语句返回:

view plain
  1. mRemote.transact(Stub.TRANSACTION_getVal,_data,_reply,0);

并将结果读出来:

view plain
  1. _result=_reply.readInt();

最后将这个结果返回到Hello.onClick函数中。

这样,Client通过HelloService的Java远程接口来使用HelloService提供的服务的过程就介绍完了。

至此,Android系统进程间通信Binder机制在应用程序框架层的Java接口源代码分析也完成了,整个Binder机制的学习就结束了。

重新学习Android系统进程间通信Binder机制,请回到Android进程间通信(IPC)机制Binder简要介绍和学习计划一文。


在前面几篇文章中,我们详细介绍了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接口,主要就是Service Manager、Server和Client这三个角色的实现了。通常,在应用程序中,我们都是把Server实现为Service的形式,并且通过IServiceManager.addService接口来把这个Service添加到Service Manager,Client也是通过IServiceManager.getService接口来获得Service接口,接着就可以使用这个Service提供的功能了,这个与运行时库的Binder接口是一致的。

前面我们学习Android硬件抽象层时,曾经在应用程序框架层中提供了一个硬件访问服务HelloService,这个Service运行在一个独立的进程中充当Server的角色,使用这个Service的Client运行在另一个进程中,它们之间就是通过Binder机制来通信的了。这里,我们就使用HelloService这个例子来分析Android系统进程间通信Binder机制在应用程序框架层的Java接口源代码。所以希望读者在阅读下面的内容之前,先了解一下前面在Ubuntu上为Android系统的Application Frameworks层增加硬件访问服务这篇文章。

这篇文章通过五个情景来学习Android系统进程间通信Binder机制在应用程序框架层的Java接口:1. 获取Service Manager的Java远程接口的过程;2. HelloService接口的定义;3. HelloService的启动过程;4. Client获取HelloService的Java远程接口的过程;5.Client通过HelloService的Java远程接口来使用HelloService提供的服务的过程。

一. 获取Service Manager的Java远程接口

我们要获取的Service Manager的Java远程接口是一个ServiceManagerProxy对象的IServiceManager接口。我们现在就来看看ServiceManagerProxy类是长什么样子的:


这里可以看出,ServiceManagerProxy类实现了IServiceManager接口,IServiceManager提供了getService和addService两个成员函数来管理系统中的Service。从ServiceManagerProxy类的构造函数可以看出,它需要一个BinderProxy对象的IBinder接口来作为参数。因此,要获取Service Manager的Java远程接口ServiceManagerProxy,首先要有一个BinderProxy对象。下面将会看到这个BinderProxy对象是如何获得的。

再来看一下是通过什么路径来获取Service Manager的Java远程接口ServiceManagerProxy的。这个主角就是ServiceManager了,我们也先看一下ServiceManager是长什么样子的:


ServiceManager类有一个静态成员函数getIServiceManager,它的作用就是用来获取Service Manager的Java远程接口了,而这个函数又是通过ServiceManagerNative来获取Service Manager的Java远程接口的。

接下来,我们就看一下ServiceManager.getIServiceManager这个函数的实现,这个函数定义在frameworks/base/core/java/android/os/ServiceManager.java文件中:

view plain
  1. publicfinalclassServiceManager{
  2. ......
  3. privatestaticIServiceManagersServiceManager;
  4. ......
  5. privatestaticIServiceManagergetIServiceManager(){
  6. if(sServiceManager!=null){
  7. returnsServiceManager;
  8. }
  9. //Findtheservicemanager
  10. sServiceManager=ServiceManagerNative.asInterface(BinderInternal.getContextObject());
  11. returnsServiceManager;
  12. }
  13. ......
  14. }
如果其静态成员变量sServiceManager尚未创建,那么就调用ServiceManagerNative.asInterface函数来创建。在调用ServiceManagerNative.asInterface函数之前,首先要通过BinderInternal.getContextObject函数来获得一个BinderProxy对象。

我们来看一下BinderInternal.getContextObject的实现,这个函数定义在frameworks/base/core/java/com/android/internal/os/BinderInternal.java文件中:

view plain
  1. publicclassBinderInternal{
  2. ......
  3. /**
  4. *Returntheglobal"contextobject"ofthesystem.Thisisusually
  5. *animplementationofIServiceManager,whichyoucanusetofind
  6. *otherservices.
  7. */
  8. publicstaticfinalnativeIBindergetContextObject();
  9. ......
  10. }
这里可以看出,BinderInternal.getContextObject是一个JNI方法,它实现在frameworks/base/core/jni/android_util_Binder.cpp文件中:
view plain
  1. staticjobjectandroid_os_BinderInternal_getContextObject(JNIEnv*env,jobjectclazz)
  2. {
  3. sp<IBinder>b=ProcessState::self()->getContextObject(NULL);
  4. returnjavaObjectForIBinder(env,b);
  5. }
这里看到我们熟悉的ProcessState::self()->getContextObject函数,具体可以参考浅谈Android系统进程间通信(IPC)机制Binder中的Server和Client获得Service Manager接口之路一文。ProcessState::self()->getContextObject函数返回一个BpBinder对象,它的句柄值是0,即下面语句:
view plain
  1. sp<IBinder>b=ProcessState::self()->getContextObject(NULL);
相当于是:
view plain
  1. sp<IBinder>b=newBpBinder(0);
接着调用javaObjectForIBinder把这个BpBinder对象转换成一个BinderProxy对象:
view plain
  1. jobjectjavaObjectForIBinder(JNIEnv*env,constsp<IBinder>&val)
  2. {
  3. if(val==NULL)returnNULL;
  4. if(val->checkSubclass(&gBinderOffsets)){
  5. //Oneofourown!
  6. jobjectobject=static_cast<JavaBBinder*>(val.get())->object();
  7. //printf("objectForBinder%p:it'sourown%p!\n",val.get(),object);
  8. returnobject;
  9. }
  10. //Fortherestofthefunctionwewillholdthislock,toserialize
  11. //looking/creationofJavaproxiesfornativeBinderproxies.
  12. AutoMutex_l(mProxyLock);
  13. //Someoneelse's...doweknowaboutit?
  14. jobjectobject=(jobject)val->findObject(&gBinderProxyOffsets);
  15. if(object!=NULL){
  16. jobjectres=env->CallObjectMethod(object,gWeakReferenceOffsets.mGet);
  17. if(res!=NULL){
  18. LOGV("objectForBinder%p:foundexisting%p!\n",val.get(),res);
  19. returnres;
  20. }
  21. LOGV("Proxyobject%pofIBinder%pnolongerinworkingset!!!",object,val.get());
  22. android_atomic_dec(&gNumProxyRefs);
  23. val->detachObject(&gBinderProxyOffsets);
  24. env->DeleteGlobalRef(object);
  25. }
  26. object=env->NewObject(gBinderProxyOffsets.mClass,gBinderProxyOffsets.mConstructor);
  27. if(object!=NULL){
  28. LOGV("objectForBinder%p:creatednew%p!\n",val.get(),object);
  29. //Theproxyholdsareferencetothenativeobject.
  30. env->SetIntField(object,gBinderProxyOffsets.mObject,(int)val.get());
  31. val->incStrong(object);
  32. //Thenativeobjectneedstoholdaweakreferencebacktothe
  33. //proxy,sowecanretrievethesameproxyifitisstillactive.
  34. jobjectrefObject=env->NewGlobalRef(
  35. env->GetObjectField(object,gBinderProxyOffsets.mSelf));
  36. val->attachObject(&gBinderProxyOffsets,refObject,
  37. jnienv_to_javavm(env),proxy_cleanup);
  38. //Notethatanewobjectreferencehasbeencreated.
  39. android_atomic_inc(&gNumProxyRefs);
  40. incRefsCreated(env);
  41. }
  42. returnobject;
  43. }
在介绍这个函数之前,先来看两个变量gBinderOffsets和gBinderProxyOffsets的定义。

先看gBinderOffsets的定义:

view plain
  1. staticstructbindernative_offsets_t
  2. {
  3. //Classstate.
  4. jclassmClass;
  5. jmethodIDmExecTransact;
  6. //Objectstate.
  7. jfieldIDmObject;
  8. }gBinderOffsets;
简单来说,gBinderOffsets变量是用来记录上面第二个类图中的Binder类的相关信息的,它是在注册Binder类的JNI方法的int_register_android_os_Binder函数初始化的:
view plain
  1. constchar*constkBinderPathName="android/os/Binder";
  2. staticintint_register_android_os_Binder(JNIEnv*env)
  3. {
  4. jclassclazz;
  5. clazz=env->FindClass(kBinderPathName);
  6. LOG_FATAL_IF(clazz==NULL,"Unabletofindclassandroid.os.Binder");
  7. gBinderOffsets.mClass=(jclass)env->NewGlobalRef(clazz);
  8. gBinderOffsets.mExecTransact
  9. =env->GetMethodID(clazz,"execTransact","(IIII)Z");
  10. assert(gBinderOffsets.mExecTransact);
  11. gBinderOffsets.mObject
  12. =env->GetFieldID(clazz,"mObject","I");
  13. assert(gBinderOffsets.mObject);
  14. returnAndroidRuntime::registerNativeMethods(
  15. env,kBinderPathName,
  16. gBinderMethods,NELEM(gBinderMethods));
  17. }

再来看gBinderProxyOffsets的定义:

view plain
  1. staticstructbinderproxy_offsets_t
  2. {
  3. //Classstate.
  4. jclassmClass;
  5. jmethodIDmConstructor;
  6. jmethodIDmSendDeathNotice;
  7. //Objectstate.
  8. jfieldIDmObject;
  9. jfieldIDmSelf;
  10. }gBinderProxyOffsets;

简单来说,gBinderProxyOffsets是用来变量是用来记录上面第一个图中的BinderProxy类的相关信息的,它是在注册BinderProxy类的JNI方法的int_register_android_os_BinderProxy函数初始化的:

view plain
  1. constchar*constkBinderProxyPathName="android/os/BinderProxy";
  2. staticintint_register_android_os_BinderProxy(JNIEnv*env)
  3. {
  4. jclassclazz;
  5. clazz=env->FindClass("java/lang/ref/WeakReference");
  6. LOG_FATAL_IF(clazz==NULL,"Unabletofindclassjava.lang.ref.WeakReference");
  7. gWeakReferenceOffsets.mClass=(jclass)env->NewGlobalRef(clazz);
  8. gWeakReferenceOffsets.mGet
  9. =env->GetMethodID(clazz,"get","()Ljava/lang/Object;");
  10. assert(gWeakReferenceOffsets.mGet);
  11. clazz=env->FindClass("java/lang/Error");
  12. LOG_FATAL_IF(clazz==NULL,"Unabletofindclassjava.lang.Error");
  13. gErrorOffsets.mClass=(jclass)env->NewGlobalRef(clazz);
  14. clazz=env->FindClass(kBinderProxyPathName);
  15. LOG_FATAL_IF(clazz==NULL,"Unabletofindclassandroid.os.BinderProxy");
  16. gBinderProxyOffsets.mClass=(jclass)env->NewGlobalRef(clazz);
  17. gBinderProxyOffsets.mConstructor
  18. =env->GetMethodID(clazz,"<init>","()V");
  19. assert(gBinderProxyOffsets.mConstructor);
  20. gBinderProxyOffsets.mSendDeathNotice
  21. =env->GetStaticMethodID(clazz,"sendDeathNotice","(Landroid/os/IBinder$DeathRecipient;)V");
  22. assert(gBinderProxyOffsets.mSendDeathNotice);
  23. gBinderProxyOffsets.mObject
  24. =env->GetFieldID(clazz,"mObject","I");
  25. assert(gBinderProxyOffsets.mObject);
  26. gBinderProxyOffsets.mSelf
  27. =env->GetFieldID(clazz,"mSelf","Ljava/lang/ref/WeakReference;");
  28. assert(gBinderProxyOffsets.mSelf);
  29. returnAndroidRuntime::registerNativeMethods(
  30. env,kBinderProxyPathName,
  31. gBinderProxyMethods,NELEM(gBinderProxyMethods));
  32. }
回到前面的javaObjectForIBinder函数中,下面这段代码:
view plain
  1. if(val->checkSubclass(&gBinderOffsets)){
  2. //Oneofourown!
  3. jobjectobject=static_cast<JavaBBinder*>(val.get())->object();
  4. //printf("objectForBinder%p:it'sourown%p!\n",val.get(),object);
  5. returnobject;
  6. }
前面说过,这里传进来的参数是一个BpBinder的指针,而BpBinder::checkSubclass继承于父类IBinder::checkSubclass,它什么也不做就返回false。

于是函数继续往下执行:

view plain
  1. jobjectobject=(jobject)val->findObject(&gBinderProxyOffsets);
由于这个BpBinder对象是第一创建,它里面什么对象也没有,因此,这里返回的object为NULL。

于是函数又继续往下执行:

view plain
  1. object=env->NewObject(gBinderProxyOffsets.mClass,gBinderProxyOffsets.mConstructor);
这里,就创建了一个BinderProxy对象了。创建了之后,要把这个BpBinder对象和这个BinderProxy对象关联起来:

view plain
  1. env->SetIntField(object,gBinderProxyOffsets.mObject,(int)val.get());
就是通过BinderProxy.mObject成员变量来关联的了,BinderProxy.mObject成员变量记录了这个BpBinder对象的地址。

接下去,还要把它放到BpBinder里面去,下次就要使用时,就可以在上一步调用BpBinder::findObj把它找回来了:

view plain
  1. val->attachObject(&gBinderProxyOffsets,refObject,
  2. jnienv_to_javavm(env),proxy_cleanup);
最后,就把这个BinderProxy返回到android_os_BinderInternal_getContextObject函数,最终返回到最开始的ServiceManager.getIServiceManager函数中来了,于是,我们就获得一个BinderProxy对象了。

回到ServiceManager.getIServiceManager中,从下面语句返回:

view plain
  1. sServiceManager=ServiceManagerNative.asInterface(BinderInternal.getContextObject());

相当于是:

view plain
  1. sServiceManager=ServiceManagerNative.asInterface(newBinderProxy());

接下去就是调用ServiceManagerNative.asInterface函数了,这个函数定义在frameworks/base/core/java/android/os/ServiceManagerNative.java文件中:

view plain
  1. publicabstractclassServiceManagerNative......
  2. {
  3. ......
  4. staticpublicIServiceManagerasInterface(IBinderobj)
  5. {
  6. if(obj==null){
  7. returnnull;
  8. }
  9. IServiceManagerin=
  10. (IServiceManager)obj.queryLocalInterface(descriptor);
  11. if(in!=null){
  12. returnin;
  13. }
  14. returnnewServiceManagerProxy(obj);
  15. }
  16. ......
  17. }
这里的参数obj是一个BinderProxy对象,它的queryLocalInterface函数返回null。因此,最终以这个BinderProxy对象为参数创建一个ServiceManagerProxy对象。

返回到ServiceManager.getIServiceManager中,从下面语句返回:

view plain
  1. sServiceManager=ServiceManagerNative.asInterface(newBinderProxy());

就相当于是:

view plain
  1. sServiceManager=newServiceManagerProxy(newBinderProxy());
于是,我们的目标终于完成了。

总结一下,就是在Java层,我们拥有了一个Service Manager远程接口ServiceManagerProxy,而这个ServiceManagerProxy对象在JNI层有一个句柄值为0的BpBinder对象与之通过gBinderProxyOffsets关联起来。

这样获取Service Manager的Java远程接口的过程就完成了。

二.HelloService接口的定义

前面我们在学习Android系统的硬件抽象层(HAL)时,在在Ubuntu上为Android系统的Application Frameworks层增加硬件访问服务这篇文章中,我们编写了一个硬件服务HelloService,它的服务接口定义在frameworks/base/core/java/android/os/IHelloService.aidl文件中:

view plain
  1. packageandroid.os;
  2. interfaceIHelloService
  3. {
  4. voidsetVal(intval);
  5. intgetVal();
  6. }

这个服务接口很简单,只有两个函数,分别用来读写硬件寄存器。

注意,这是一个aidl文件,编译后会生成一个IHelloService.java。我们来看一下这个文件的内容隐藏着什么奥秘,可以这么神奇地支持进程间通信。

view plain
  1. /*
  2. *Thisfileisauto-generated.DONOTMODIFY.
  3. *Originalfile:frameworks/base/core/java/android/os/IHelloService.aidl
  4. */
  5. packageandroid.os;
  6. publicinterfaceIHelloServiceextendsandroid.os.IInterface
  7. {
  8. /**Local-sideIPCimplementationstubclass.*/
  9. publicstaticabstractclassStubextendsandroid.os.Binderimplementsandroid.os.IHelloService
  10. {
  11. privatestaticfinaljava.lang.StringDESCRIPTOR="android.os.IHelloService";
  12. /**Constructthestubatattachittotheinterface.*/
  13. publicStub()
  14. {
  15. this.attachInterface(this,DESCRIPTOR);
  16. }
  17. /**
  18. *CastanIBinderobjectintoanandroid.os.IHelloServiceinterface,
  19. *generatingaproxyifneeded.
  20. */
  21. publicstaticandroid.os.IHelloServiceasInterface(android.os.IBinderobj)
  22. {
  23. if((obj==null)){
  24. returnnull;
  25. }
  26. android.os.IInterfaceiin=(android.os.IInterface)obj.queryLocalInterface(DESCRIPTOR);
  27. if(((iin!=null)&&(iininstanceofandroid.os.IHelloService))){
  28. return((android.os.IHelloService)iin);
  29. }
  30. returnnewandroid.os.IHelloService.Stub.Proxy(obj);
  31. }
  32. publicandroid.os.IBinderasBinder()
  33. {
  34. returnthis;
  35. }
  36. @Override
  37. publicbooleanonTransact(intcode,android.os.Parceldata,android.os.Parcelreply,intflags)throwsandroid.os.RemoteException
  38. {
  39. switch(code)
  40. {
  41. caseINTERFACE_TRANSACTION:
  42. {
  43. reply.writeString(DESCRIPTOR);
  44. returntrue;
  45. }
  46. caseTRANSACTION_setVal:
  47. {
  48. data.enforceInterface(DESCRIPTOR);
  49. int_arg0;
  50. _arg0=data.readInt();
  51. this.setVal(_arg0);
  52. reply.writeNoException();
  53. returntrue;
  54. }
  55. caseTRANSACTION_getVal:
  56. {
  57. data.enforceInterface(DESCRIPTOR);
  58. int_result=this.getVal();
  59. reply.writeNoException();
  60. reply.writeInt(_result);
  61. returntrue;
  62. }
  63. }
  64. returnsuper.onTransact(code,data,reply,flags);
  65. }
  66. privatestaticclassProxyimplementsandroid.os.IHelloService
  67. {
  68. privateandroid.os.IBindermRemote;
  69. Proxy(android.os.IBinderremote)
  70. {
  71. mRemote=remote;
  72. }
  73. publicandroid.os.IBinderasBinder()
  74. {
  75. returnmRemote;
  76. }
  77. publicjava.lang.StringgetInterfaceDescriptor()
  78. {
  79. returnDESCRIPTOR;
  80. }
  81. publicvoidsetVal(intval)throwsandroid.os.RemoteException
  82. {
  83. android.os.Parcel_data=android.os.Parcel.obtain();
  84. android.os.Parcel_reply=android.os.Parcel.obtain();
  85. try{
  86. _data.writeInterfaceToken(DESCRIPTOR);
  87. _data.writeInt(val);
  88. mRemote.transact(Stub.TRANSACTION_setVal,_data,_reply,0);
  89. _reply.readException();
  90. }
  91. finally{
  92. _reply.recycle();
  93. _data.recycle();
  94. }
  95. }
  96. publicintgetVal()throwsandroid.os.RemoteException
  97. {
  98. android.os.Parcel_data=android.os.Parcel.obtain();
  99. android.os.Parcel_reply=android.os.Parcel.obtain();
  100. int_result;
  101. try{
  102. _data.writeInterfaceToken(DESCRIPTOR);
  103. mRemote.transact(Stub.TRANSACTION_getVal,_data,_reply,0);
  104. _reply.readException();
  105. _result=_reply.readInt();
  106. }
  107. finally{
  108. _reply.recycle();
  109. _data.recycle();
  110. }
  111. return_result;
  112. }
  113. }
  114. staticfinalintTRANSACTION_setVal=(android.os.IBinder.FIRST_CALL_TRANSACTION+0);
  115. staticfinalintTRANSACTION_getVal=(android.os.IBinder.FIRST_CALL_TRANSACTION+1);
  116. }
  117. publicvoidsetVal(intval)throwsandroid.os.RemoteException;
  118. publicintgetVal()throwsandroid.os.RemoteException;
  119. }

这里我们可以看到IHelloService.aidl这个文件编译后的真面目,原来就是根据IHelloService接口的定义生成相应的Stub和Proxy类,这个就是我们熟悉的Binder机制的内容了,即实现这个HelloService的Server必须继续于这里的IHelloService.Stub类,而这个HelloService的远程接口就是这里的IHelloService.Stub.Proxy对象获得的IHelloService接口。接下来的内容,我们就可以看到IHelloService.Stub和IHelloService.Stub.Proxy是怎么创建或者使用的。

三.HelloService的启动过程

在讨论HelloService的启动过程之前,我们先来看一下实现HelloService接口的Server是怎么定义的。

回忆在Ubuntu上为Android系统的Application Frameworks层增加硬件访问服务一文,我们在frameworks/base/services/java/com/android/server目录下新增了一个HelloService.java文件:

view plain
  1. packagecom.android.server;
  2. importandroid.content.Context;
  3. importandroid.os.IHelloService;
  4. importandroid.util.Slog;
  5. publicclassHelloServiceextendsIHelloService.Stub{
  6. privatestaticfinalStringTAG="HelloService";
  7. HelloService(){
  8. init_native();
  9. }
  10. publicvoidsetVal(intval){
  11. setVal_native(val);
  12. }
  13. publicintgetVal(){
  14. returngetVal_native();
  15. }
  16. privatestaticnativebooleaninit_native();
  17. privatestaticnativevoidsetVal_native(intval);
  18. privatestaticnativeintgetVal_native();
  19. }

这里,我们可以看到,HelloService继续了IHelloService.Stub类,它通过本地方法调用实现了getVal和setVal两个函数。我们不关心这两个函数的具体实现,有兴趣的读者可以参考在Ubuntu上为Android系统的Application Frameworks层增加硬件访问服务一文。
有了HelloService这个Server类后,下一步就是考虑怎么样把它启动起来了。在frameworks/base/services/java/com/android/server/SystemServer.java文件中,定义了SystemServer类。SystemServer对象是在系统启动的时候创建的,它被创建的时候会启动一个线程来创建HelloService,并且把它添加到Service Manager中去。

我们来看一下这部份的代码:

view plain
  1. classServerThreadextendsThread{
  2. ......
  3. @Override
  4. publicvoidrun(){
  5. ......
  6. Looper.prepare();
  7. ......
  8. try{
  9. Slog.i(TAG,"HelloService");
  10. ServiceManager.addService("hello",newHelloService());
  11. }catch(Throwablee){
  12. Slog.e(TAG,"FailurestartingHelloService",e);
  13. }
  14. ......
  15. Looper.loop();
  16. ......
  17. }
  18. }
  19. ......
  20. publicclassSystemServer
  21. {
  22. ......
  23. /**
  24. *ThismethodiscalledfromZygotetoinitializethesystem.Thiswillcausethenative
  25. *services(SurfaceFlinger,AudioFlinger,etc..)tobestarted.Afterthatitwillcallback
  26. *upintoinit2()tostarttheAndroidservices.
  27. */
  28. nativepublicstaticvoidinit1(String[]args);
  29. ......
  30. publicstaticfinalvoidinit2(){
  31. Slog.i(TAG,"EnteredtheAndroidsystemserver!");
  32. Threadthr=newServerThread();
  33. thr.setName("android.server.ServerThread");
  34. thr.start();
  35. }
  36. ......
  37. }

这里,我们可以看到,在ServerThread.run函数中,执行了下面代码把HelloService添加到Service Manager中去。这里我们关注把HelloService添加到Service Manager中去的代码:

view plain
  1. try{
  2. Slog.i(TAG,"HelloService");
  3. ServiceManager.addService("hello",newHelloService());
  4. }catch(Throwablee){
  5. Slog.e(TAG,"FailurestartingHelloService",e);
  6. }

通过调用ServiceManager.addService把一个HelloService实例添加到Service Manager中去。

我们先来看一下HelloService的创建过程:

view plain
  1. newHelloService();

这个语句会调用HelloService类的构造函数,而HelloService类继承于IHelloService.Stub类,IHelloService.Stub类又继承了Binder类,因此,最后会调用Binder类的构造函数:

view plain
  1. publicclassBinderimplementsIBinder{
  2. ......
  3. privateintmObject;
  4. ......
  5. publicBinder(){
  6. init();
  7. ......
  8. }
  9. privatenativefinalvoidinit();
  10. ......
  11. }

这里调用了一个JNI方法init来初始化这个Binder对象,这个JNI方法定义在frameworks/base/core/jni/android_util_Binder.cpp文件中:

view plain
  1. staticvoidandroid_os_Binder_init(JNIEnv*env,jobjectclazz)
  2. {
  3. JavaBBinderHolder*jbh=newJavaBBinderHolder(env,clazz);
  4. if(jbh==NULL){
  5. jniThrowException(env,"java/lang/OutOfMemoryError",NULL);
  6. return;
  7. }
  8. LOGV("JavaBinder%p:acquiringfirstrefonholder%p",clazz,jbh);
  9. jbh->incStrong(clazz);
  10. env->SetIntField(clazz,gBinderOffsets.mObject,(int)jbh);
  11. }
它实际上只做了一件事情,就是创建一个JavaBBinderHolder对象jbh,然后把这个对象的地址保存在上面的Binder类的mObject成员变量中,后面我们会用到。

回到ServerThread.run函数中,我们再来看一下ServiceManager.addService函数的实现:

view plain
  1. publicfinalclassServiceManager{
  2. ......
  3. privatestaticIServiceManagersServiceManager;
  4. ......
  5. publicstaticvoidaddService(Stringname,IBinderservice){
  6. try{
  7. getIServiceManager().addService(name,service);
  8. }catch(RemoteExceptione){
  9. Log.e(TAG,"errorinaddService",e);
  10. }
  11. }
  12. ......
  13. }

这里的getIServiceManager函数我们在前面已经分析过了,它返回的是一个ServiceManagerProxy对象的IServiceManager接口。因此,我们进入到ServiceManagerProxy.addService中去看看:

view plain
  1. classServiceManagerProxyimplementsIServiceManager{
  2. publicServiceManagerProxy(IBinderremote){
  3. mRemote=remote;
  4. }
  5. ......
  6. publicvoidaddService(Stringname,IBinderservice)
  7. throwsRemoteException{
  8. Parceldata=Parcel.obtain();
  9. Parcelreply=Parcel.obtain();
  10. data.writeInterfaceToken(IServiceManager.descriptor);
  11. data.writeString(name);
  12. data.writeStrongBinder(service);
  13. mRemote.transact(ADD_SERVICE_TRANSACTION,data,reply,0);
  14. reply.recycle();
  15. data.recycle();
  16. }
  17. ......
  18. privateIBindermRemote;
  19. }

这里的Parcel类是用Java来实现的,它跟我们前面几篇文章介绍Binder机制时提到的用C++实现的Parcel类的作用是一样的,即用来在两个进程之间传递数据。

这里我们关注是如何把参数service写到data这个Parcel对象中去的:

view plain
  1. data.writeStrongBinder(service);

我们来看看Parcel.writeStrongBinder函数的实现:

view plain
  1. publicfinalclassParcel{
  2. ......
  3. /**
  4. *WriteanobjectintotheparcelatthecurrentdataPosition(),
  5. *growingdataCapacity()ifneeded.
  6. */
  7. publicfinalnativevoidwriteStrongBinder(IBinderval);
  8. ......
  9. }

这里的writeStrongBinder函数又是一个JNI方法,它定义在frameworks/base/core/jni/android_util_Binder.cpp文件中:

view plain
  1. staticvoidandroid_os_Parcel_writeStrongBinder(JNIEnv*env,jobjectclazz,jobjectobject)
  2. {
  3. Parcel*parcel=parcelForJavaObject(env,clazz);
  4. if(parcel!=NULL){
  5. conststatus_terr=parcel->writeStrongBinder(ibinderForJavaObject(env,object));
  6. if(err!=NO_ERROR){
  7. jniThrowException(env,"java/lang/OutOfMemoryError",NULL);
  8. }
  9. }
  10. }
这里的clazz参数是一个Java语言实现的Parcel对象,通过parcelForJavaObject把它转换成C++语言实现的Parcel对象。这个函数的实现我们就不看了,有兴趣的读者可以研究一下,这个函数也是实现在frameworks/base/core/jni/android_util_Binder.cpp这个文件中。
这里的object参数是一个Java语言实现的Binder对象,在调用C++语言实现的Parcel::writeStrongBinder把这个对象写入到parcel对象时,首先通过ibinderForJavaObject函数把这个Java语言实现的Binder对象转换为C++语言实现的JavaBBinderHolder对象:
view plain
  1. sp<IBinder>ibinderForJavaObject(JNIEnv*env,jobjectobj)
  2. {
  3. if(obj==NULL)returnNULL;
  4. if(env->IsInstanceOf(obj,gBinderOffsets.mClass)){
  5. JavaBBinderHolder*jbh=(JavaBBinderHolder*)
  6. env->GetIntField(obj,gBinderOffsets.mObject);
  7. returnjbh!=NULL?jbh->get(env):NULL;
  8. }
  9. if(env->IsInstanceOf(obj,gBinderProxyOffsets.mClass)){
  10. return(IBinder*)
  11. env->GetIntField(obj,gBinderProxyOffsets.mObject);
  12. }
  13. LOGW("ibinderForJavaObject:%pisnotaBinderobject",obj);
  14. returnNULL;
  15. }

我们知道,这里的obj参数是一个Binder类的实例,因此,这里会进入到第一个if语句中去。

在前面创建HelloService对象,曾经在调用到HelloService的父类Binder中,曾经在JNI层创建了一个JavaBBinderHolder对象,然后把这个对象的地址保存在Binder类的mObject成员变量中,因此,这里把obj对象的mObject成员变量强制转为JavaBBinderHolder对象。

到了这里,这个函数的功课还未完成,还剩下最后关键的一步:

view plain
  1. returnjbh!=NULL?jbh->get(env):NULL;

这里就是jbh->get这个语句了。

在JavaBBinderHolder类中,有一个成员变量mBinder,它的类型为JavaBBinder,而JavaBBinder类继承于BBinder类。在前面学习Binder机制的C++语言实现时,我们在Android系统进程间通信(IPC)机制Binder中的Server启动过程源代码分析这篇文章中,曾经介绍过,IPCThreadState类负责与Binder驱动程序进行交互,它把从Binder驱动程序读出来的请求作简单的处理后,最后把这个请求扔给BBinder的onTransact函数来进一步处理。

这里,我们就是要把JavaBBinderHolder里面的JavaBBinder类型Binder实体添加到Service Manager中去,以便使得这个HelloService有Client来请求服务时,由Binder驱动程序来唤醒这个Server线程,进而调用这个JavaBBinder类型Binder实体的onTransact函数来进一步处理,这个函数我们在后面会继续介绍。

先来看一下JavaBBinderHolder::get函数的实现:

view plain
  1. classJavaBBinderHolder:publicRefBase
  2. {
  3. ......
  4. JavaBBinderHolder(JNIEnv*env,jobjectobject)
  5. :mObject(object)
  6. {
  7. ......
  8. }
  9. ......
  10. sp<JavaBBinder>get(JNIEnv*env)
  11. {
  12. AutoMutex_l(mLock);
  13. sp<JavaBBinder>b=mBinder.promote();
  14. if(b==NULL){
  15. b=newJavaBBinder(env,mObject);
  16. mBinder=b;
  17. ......
  18. }
  19. returnb;
  20. }
  21. ......
  22. jobjectmObject;
  23. wp<JavaBBinder>mBinder;
  24. };

这里是第一次调用get函数,因此,会创建一个JavaBBinder对象,并且保存在mBinder成员变量中。注意,这里的mObject就是上面创建的HelloService对象了,这是一个Java对象。这个HelloService对象最终也会保存在JavaBBinder对象的成员变量mObject中。

回到android_os_Parcel_writeStrongBinder函数中,下面这个语句:

view plain
  1. conststatus_terr=parcel->writeStrongBinder(ibinderForJavaObject(env,object));
相当于是:
view plain
  1. conststatus_terr=parcel->writeStrongBinder((JavaBBinderHodler*)(obj.mObject));
因此,这里的效果相当于是写入了一个JavaBBinder类型的Binder实体到parcel中去。这与我们前面介绍的Binder机制的C++实现是一致的。

接着,再回到ServiceManagerProxy.addService这个函数中,最后它通过其成员变量mRemote来执行进程间通信操作。前面我们在介绍如何获取Service Manager远程接口时提到,这里的mRemote成员变量实际上是一个BinderProxy对象,因此,我们再来看看BinderProxy.transact函数的实现:

view plain
  1. finalclassBinderProxyimplementsIBinder{
  2. ......
  3. publicnativebooleantransact(intcode,Parceldata,Parcelreply,
  4. intflags)throwsRemoteException;
  5. ......
  6. }

这里的transact成员函数又是一个JNI方法,它定义在frameworks/base/core/jni/android_util_Binder.cpp文件中:

view plain
  1. staticjbooleanandroid_os_BinderProxy_transact(JNIEnv*env,jobjectobj,
  2. jintcode,jobjectdataObj,
  3. jobjectreplyObj,jintflags)
  4. {
  5. ......
  6. Parcel*data=parcelForJavaObject(env,dataObj);
  7. if(data==NULL){
  8. returnJNI_FALSE;
  9. }
  10. Parcel*reply=parcelForJavaObject(env,replyObj);
  11. if(reply==NULL&&replyObj!=NULL){
  12. returnJNI_FALSE;
  13. }
  14. IBinder*target=(IBinder*)
  15. env->GetIntField(obj,gBinderProxyOffsets.mObject);
  16. if(target==NULL){
  17. jniThrowException(env,"java/lang/IllegalStateException","Binderhasbeenfinalized!");
  18. returnJNI_FALSE;
  19. }
  20. ......
  21. status_terr=target->transact(code,*data,reply,flags);
  22. ......
  23. if(err==NO_ERROR){
  24. returnJNI_TRUE;
  25. }elseif(err==UNKNOWN_TRANSACTION){
  26. returnJNI_FALSE;
  27. }
  28. signalExceptionForError(env,obj,err);
  29. returnJNI_FALSE;
  30. }

这里传进来的参数dataObj和replyObj是一个Java接口实现的Parcel类,由于这里是JNI层,需要把它转换为C++实现的Parcel类,它们就是通过我们前面说的parcelForJavaObject函数进行转换的。

前面我们在分析如何获取Service Manager远程接口时,曾经说到,在JNI层中,创建了一个BpBinder对象,它的句柄值为0,它的地址保存在gBinderProxyOffsets.mObject中,因此,这里通过下面语句得到这个BpBinder对象的IBinder接口:

view plain
  1. IBinder*target=(IBinder*)
  2. env->GetIntField(obj,gBinderProxyOffsets.mObject);

有了这个IBinder接口后,就和我们前面几篇文章介绍Binder机制的C/C++实现一致了。

最后,通过BpBinder::transact函数进入到Binder驱动程序,然后Binder驱动程序唤醒Service Manager响应这个ADD_SERVICE_TRANSACTION请求:

view plain
  1. status_terr=target->transact(code,*data,reply,flags);

具体可以参考Android系统进程间通信(IPC)机制Binder中的Server启动过程源代码分析一文。需要注意的是,这里的data包含了一个JavaBBinderHolder类型的Binder实体对象,它就代表了我们上面创建的HelloService。Service Manager收到这个ADD_SERVICE_TRANSACTION请求时,就会把这个Binder实体纳入到自己内部进行管理。
这样,实现HelloService的Server的启动过程就完成了。

四.Client获取HelloService的Java远程接口的过程

前面我们在学习Android系统硬件抽象层(HAL)时,在在Ubuntu上为Android系统内置Java应用程序测试Application Frameworks层的硬件服务这篇文章中,我们创建了一个应用程序,这个应用程序作为一个Client角色,借助Service Manager这个Java远程接口来获得HelloService的远程接口,进而调用HelloService提供的服务。

我们看看它是如何借助Service Manager这个Java远程接口来获得HelloService的远程接口的。在Hello这个Activity的onCreate函数,通过IServiceManager.getService函数来获得HelloService的远程接口:

view plain
  1. publicclassHelloextendsActivityimplementsOnClickListener{
  2. ......
  3. privateIHelloServicehelloService=null;
  4. ......
  5. @Override
  6. publicvoidonCreate(BundlesavedInstanceState){
  7. helloService=IHelloService.Stub.asInterface(
  8. ServiceManager.getService("hello"));
  9. }
  10. ......
  11. }

我们先来看ServiceManager.getService的实现。前面我们说过,这里实际上是调用了ServiceManagerProxy.getService函数:

view plain
  1. classServiceManagerProxyimplementsIServiceManager{
  2. publicServiceManagerProxy(IBinderremote){
  3. mRemote=remote;
  4. }
  5. ......
  6. publicIBindergetService(Stringname)throwsRemoteException{
  7. Parceldata=Parcel.obtain();
  8. Parcelreply=Parcel.obtain();
  9. data.writeInterfaceToken(IServiceManager.descriptor);
  10. data.writeString(name);
  11. mRemote.transact(GET_SERVICE_TRANSACTION,data,reply,0);
  12. IBinderbinder=reply.readStrongBinder();
  13. reply.recycle();
  14. data.recycle();
  15. returnbinder;
  16. }
  17. ......
  18. privateIBindermRemote;
  19. }

最终通过mRemote.transact来执行实际操作。我们在前面已经介绍过了,这里的mRemote实际上是一个BinderProxy对象,它的transact成员函数是一个JNI方法,实现在frameworks/base/core/jni/android_util_Binder.cpp文件中的android_os_BinderProxy_transact函数中。

这个函数前面我们已经看到了,这里就不再列出来了。不过,当这个函数从:

view plain
  1. status_terr=target->transact(code,*data,reply,flags);

这里的reply变量里面就包括了一个HelloService的引用了。注意,这里的reply变量就是我们在ServiceManagerProxy.getService函数里面传进来的参数reply,它是一个Parcel对象。

回到ServiceManagerProxy.getService函数中,从下面语句返回:

view plain
  1. mRemote.transact(GET_SERVICE_TRANSACTION,data,reply,0);

接着,就通过下面语句将这个HelloService的引用读出来:

view plain
  1. IBinderbinder=reply.readStrongBinder();

我们看看Parcel.readStrongBinder的实现:

view plain
  1. publicfinalclassParcel{
  2. ......
  3. /**
  4. *ReadanobjectfromtheparcelatthecurrentdataPosition().
  5. */
  6. publicfinalnativeIBinderreadStrongBinder();
  7. ......
  8. }

它也是一个JNI方法,实现在frameworks/base/core/jni/android_util_Binder.cpp文件中:

view plain
  1. staticjobjectandroid_os_Parcel_readStrongBinder(JNIEnv*env,jobjectclazz)
  2. {
  3. Parcel*parcel=parcelForJavaObject(env,clazz);
  4. if(parcel!=NULL){
  5. returnjavaObjectForIBinder(env,parcel->readStrongBinder());
  6. }
  7. returnNULL;
  8. }

这里首先把Java语言实现的Parcel对象class转换成C++语言实现的Parcel对象parcel,接着,通过parcel->readStrongBinder函数来获得一个Binder引用。

我们在前面学习Binder机制时,在Android系统进程间通信(IPC)机制Binder中的Client获得Server远程接口过程源代码分析这篇文章中,曾经分析过这个函数,它最终返回来的是一个BpBinder对象,因此,下面的语句:

view plain
  1. returnjavaObjectForIBinder(env,parcel->readStrongBinder());

就相当于是:

view plain
  1. returnjavaObjectForIBinder(env,newBpBinder(handle));

这里的handle就是HelloService这个Binder实体在Client进程中的句柄了,它是由Binder驱动程序设置的,上层不用关心它的值具体是多少。至于javaObjectForIBinder这个函数,我们前面介绍如何获取Service Manager的Java远程接口时已经有详细介绍,这里就不累述了,它的作用就是创建一个BinderProxy对象,并且把刚才获得的BpBinder对象的地址保存在这个BinderProxy对象的mObject成员变量中。

最后返回到Hello.onCreate函数中,从下面语句返回:

view plain
  1. helloService=IHelloService.Stub.asInterface(
  2. ServiceManager.getService("hello"));

就相当于是:

view plain
  1. helloService=IHelloService.Stub.asInterface(newBinderProxy()));

回忆一下前面介绍IHelloService接口的定义时,IHelloService.Stub.asInterface是这样定义的:

view plain
  1. publicinterfaceIHelloServiceextendsandroid.os.IInterface
  2. {
  3. /**Local-sideIPCimplementationstubclass.*/
  4. publicstaticabstractclassStubextendsandroid.os.Binderimplementsandroid.os.IHelloService
  5. {
  6. ......
  7. publicstaticandroid.os.IHelloServiceasInterface(android.os.IBinderobj)
  8. {
  9. if((obj==null)){
  10. returnnull;
  11. }
  12. android.os.IInterfaceiin=(android.os.IInterface)obj.queryLocalInterface(DESCRIPTOR);
  13. if(((iin!=null)&&(iininstanceofandroid.os.IHelloService))){
  14. return((android.os.IHelloService)iin);
  15. }
  16. returnnewandroid.os.IHelloService.Stub.Proxy(obj);
  17. }
  18. ......
  19. }
  20. }

这里的obj是一个BinderProxy对象,它的queryLocalInterface返回null,于是调用下面语句获得HelloService的远程接口:

view plain
  1. returnnewandroid.os.IHelloService.Stub.Proxy(obj);

相当于是:

view plain
  1. returnnewandroid.os.IHelloService.Stub.Proxy(newBinderProxy());

这样,我们就获得了HelloService的远程接口了,它实质上是一个实现了IHelloService接口的IHelloService.Stub.Proxy对象。

五.Client通过HelloService的Java远程接口来使用HelloService提供的服务的过程

上面介绍的Hello这个Activity获得了HelloService的远程接口后,就可以使用它的服务了。

我们以使用IHelloService.getVal函数为例详细说明。在Hello::onClick函数中调用了IHelloService.getVal函数:

view plain
  1. publicclassHelloextendsActivityimplementsOnClickListener{
  2. ......
  3. @Override
  4. publicvoidonClick(Viewv){
  5. if(v.equals(readButton)){
  6. intval=helloService.getVal();
  7. ......
  8. }
  9. elseif(v.equals(writeButton)){
  10. ......
  11. }
  12. elseif(v.equals(clearButton)){
  13. ......
  14. }
  15. }
  16. ......
  17. }

通知前面的分析,我们知道,这里的helloService接口实际上是一个IHelloService.Stub.Proxy对象,因此,我们进入到IHelloService.Stub.Proxy类的getVal函数中:

view plain
  1. publicinterfaceIHelloServiceextendsandroid.os.IInterface
  2. {
  3. /**Local-sideIPCimplementationstubclass.*/
  4. publicstaticabstractclassStubextendsandroid.os.Binderimplementsandroid.os.IHelloService
  5. {
  6. ......
  7. privatestaticclassProxyimplementsandroid.os.IHelloService
  8. {
  9. privateandroid.os.IBindermRemote;
  10. ......
  11. publicintgetVal()throwsandroid.os.RemoteException
  12. {
  13. android.os.Parcel_data=android.os.Parcel.obtain();
  14. android.os.Parcel_reply=android.os.Parcel.obtain();
  15. int_result;
  16. try{
  17. _data.writeInterfaceToken(DESCRIPTOR);
  18. mRemote.transact(Stub.TRANSACTION_getVal,_data,_reply,0);
  19. _reply.readException();
  20. _result=_reply.readInt();
  21. }
  22. finally{
  23. _reply.recycle();
  24. _data.recycle();
  25. }
  26. return_result;
  27. }
  28. }
  29. ......
  30. staticfinalintTRANSACTION_getVal=(android.os.IBinder.FIRST_CALL_TRANSACTION+1);
  31. }
  32. ......
  33. }

这里我们可以看出,实际上是通过mRemote.transact来请求HelloService执行TRANSACTION_getVal操作。这里的mRemote是一个BinderProxy对象,这是我们在前面获取HelloService的Java远程接口的过程中创建的。

BinderProxy.transact函数是一个JNI方法,我们在前面已经介绍过了,这里不再累述。最过调用到Binder驱动程序,Binder驱动程序唤醒HelloService这个Server。前面我们在介绍HelloService的启动过程时,曾经提到,HelloService这个Server线程被唤醒之后,就会调用JavaBBinder类的onTransact函数:

view plain
  1. classJavaBBinder:publicBBinder
  2. {
  3. JavaBBinder(JNIEnv*env,jobjectobject)
  4. :mVM(jnienv_to_javavm(env)),mObject(env->NewGlobalRef(object))
  5. {
  6. ......
  7. }
  8. ......
  9. virtualstatus_tonTransact(
  10. uint32_tcode,constParcel&data,Parcel*reply,uint32_tflags=0)
  11. {
  12. JNIEnv*env=javavm_to_jnienv(mVM);
  13. ......
  14. jbooleanres=env->CallBooleanMethod(mObject,gBinderOffsets.mExecTransact,
  15. code,(int32_t)&data,(int32_t)reply,flags);
  16. ......
  17. returnres!=JNI_FALSE?NO_ERROR:UNKNOWN_TRANSACTION;
  18. }
  19. ......
  20. JavaVM*constmVM;
  21. jobjectconstmObject;
  22. };

前面我们在介绍HelloService的启动过程时,曾经介绍过,JavaBBinder类里面的成员变量mObject就是HelloService类的一个实例对象了。因此,这里通过语句:

view plain
  1. jbooleanres=env->CallBooleanMethod(mObject,gBinderOffsets.mExecTransact,
  2. code,(int32_t)&data,(int32_t)reply,flags);

就调用了HelloService.execTransact函数,而HelloService.execTransact函数继承了Binder类的execTransact函数:

view plain
  1. publicclassBinderimplementsIBinder{
  2. ......
  3. //Entrypointfromandroid_util_Binder.cpp'sonTransact
  4. privatebooleanexecTransact(intcode,intdataObj,intreplyObj,intflags){
  5. Parceldata=Parcel.obtain(dataObj);
  6. Parcelreply=Parcel.obtain(replyObj);
  7. //theoretically,weshouldcalltransact,whichwillcallonTransact,
  8. //butallthatdoesisrewindit,andwejustgotthesefromanIPC,
  9. //sowe'lljustcallitdirectly.
  10. booleanres;
  11. try{
  12. res=onTransact(code,data,reply,flags);
  13. }catch(RemoteExceptione){
  14. reply.writeException(e);
  15. res=true;
  16. }catch(RuntimeExceptione){
  17. reply.writeException(e);
  18. res=true;
  19. }catch(OutOfMemoryErrore){
  20. RuntimeExceptionre=newRuntimeException("Outofmemory",e);
  21. reply.writeException(re);
  22. res=true;
  23. }
  24. reply.recycle();
  25. data.recycle();
  26. returnres;
  27. }
  28. }

这里又调用了onTransact函数来作进一步处理。由于HelloService类继承了IHelloService.Stub类,而IHelloService.Stub类实现了onTransact函数,HelloService类没有实现,因此,最终调用了IHelloService.Stub.onTransact函数:

view plain
  1. publicinterfaceIHelloServiceextendsandroid.os.IInterface
  2. {
  3. /**Local-sideIPCimplementationstubclass.*/
  4. publicstaticabstractclassStubextendsandroid.os.Binderimplementsandroid.os.IHelloService
  5. {
  6. ......
  7. @Override
  8. publicbooleanonTransact(intcode,android.os.Parceldata,android.os.Parcelreply,intflags)throwsandroid.os.RemoteException
  9. {
  10. switch(code)
  11. {
  12. ......
  13. caseTRANSACTION_getVal:
  14. {
  15. data.enforceInterface(DESCRIPTOR);
  16. int_result=this.getVal();
  17. reply.writeNoException();
  18. reply.writeInt(_result);
  19. returntrue;
  20. }
  21. }
  22. returnsuper.onTransact(code,data,reply,flags);
  23. }
  24. ......
  25. }
  26. }

函数最终又调用了HelloService.getVal函数:

view plain
  1. publicclassHelloServiceextendsIHelloService.Stub{
  2. ......
  3. publicintgetVal(){
  4. returngetVal_native();
  5. }
  6. ......
  7. privatestaticnativeintgetVal_native();
  8. }

最终,经过层层返回,就回到IHelloService.Stub.Proxy.getVal函数中来了,从下面语句返回:

view plain
  1. mRemote.transact(Stub.TRANSACTION_getVal,_data,_reply,0);

并将结果读出来:

view plain
  1. _result=_reply.readInt();

最后将这个结果返回到Hello.onClick函数中。

这样,Client通过HelloService的Java远程接口来使用HelloService提供的服务的过程就介绍完了。

至此,Android系统进程间通信Binder机制在应用程序框架层的Java接口源代码分析也完成了,整个Binder机制的学习就结束了。

重新学习Android系统进程间通信Binder机制,请回到Android进程间通信(IPC)机制Binder简要介绍和学习计划一文。

分享到:
评论

相关推荐

    Android系统进程间通信Binder机制在应用程序框架层的Java接口源代码分析[归纳].pdf

    Android系统进程间通信Binder机制在应用程序框架层的Java接口源代码分析[归纳].pdf

    Binder机制在应用程序框架层的Java接口源代码分析

    Android系统进程间通信Binder机制在应用程序框架层的Java接口源代码分析

    Android系统源代码情景分析光盘

    第5章 Binder进程间通信系统............................... 144 5.1 Binder驱动程序..................................................... 145 5.1.1 基础数据结构............................................

    Android系统进程间通信Binder机制在应用程序框架层的Java接口源代码分析

    本文主要介绍 Android系统进程间通信Binder机制Java 接口源码分析,这里详细介绍了如何实现Binder 机制和Java接口直接的通信,有兴趣的小伙伴可以参考下

    《Android系统源代码情景分析》

    5.10 Binder进程间通信机制的Java接口 5.10.1 Service Manager的Java代理对象的获取过程 5.10.2 Java服务接口的定义和解析 5.10.3 Java服务的启动过程 5.10.4 Java服务代理对象的获取过程 5.10.5 Java...

    Android进程间通信-Binder机制

    一.简要介绍和学习计划 二.Service Manager 成为Binder 守护进程之路 三.Server 和Client 获得Service Manager 接口之路 四.Server 启动过程源代码分析 ...应用程序框架层的Java 接口源代码分析

    Android系统源代码情景分析 PDF 完整版 ZIP.002(二个压缩包)

    在内容上,本书结合使用情景,全面、深入、细致地分析Android系统的源代码,涉及到Linux内核层、硬件抽象层(HAL)、运行时库层(Runtime)、应用程序框架层(Application Framework)以及应用程序层(Application)。...

    Android系统源代码情景分析-罗升阳-源码

    5.10 Binder进程间通信机制的Java接口 5.10.1 Service Manager的Java代理对象的获取过程 5.10.2 Java服务接口的定义和解析 5.10.3 Java服务的启动过程 5.10.4 Java服务代理对象的获取过程 5.10.5 Java服务的...

    Android系统源代码情景分析 PDF 完整版 ZIP.001(二个压缩包)

    在内容上,本书结合使用情景,全面、深入、细致地分析Android系统的源代码,涉及到Linux内核层、硬件抽象层(HAL)、运行时库层(Runtime)、应用程序框架层(Application Framework)以及应用程序层(Application)。...

    Android 代码分析

    23 如何调试跟踪Android源代码 61 24 Eclipse环境搭建 68 24.1 Eclipse 3.3 (Europa) 68 24.2 Eclipse 3.4 (Ganymede) 68 24.3 ADT 安装疑难解答 69 25 Android的底层库libutils介绍 70 25.1 libutils概述 70 25.2 ...

    Android的设计与实现 卷1 (带目录)

    Binder篇(第5~6章)着重分析了Binder在Native框架层和Java框架层的机制和实现,能让读者深入理解进程间的通信模型; 消息通信篇(第7章)重点分析了Android的消息驱动和异步处理机制,能让读者深入理解线程间的...

    Android的设计与实现(卷1)

    binder篇(第5~6章)着重分析了binder在native框架层和java框架层的机制和实现,能让读者深入理解进程间的通信模型;消息通信篇(第7章)重点分析了android的消息驱动和异步处理机制,能让读者深入理解线程间的通信...

    深入理解Android:卷I--详细书签版

     结合实际应用开发需求,以情景分析的方式有针对性地对Android的源代码进行了十分详尽的剖析,深刻揭示Android系统的工作原理  机锋网、51CTO、开源中国社区等专业技术网站一致鼎力推荐 内容简介  《深入理解...

Global site tag (gtag.js) - Google Analytics