【Android源码 栏目提醒】:网学会员在Android源码 频道为大家收集整理了“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 系统的 ApplicationFrameworks 层增加硬件访问服务这篇文章。
这篇文章通过五个情景来学习
Android 系统进程间通信 Binder 机制在应用程序框架层的 Java 接口:1. 获取 Service Manager 的 Java 远程接口的过程;2.HelloService 接口的定义; HelloService 的启动过程; Client 获取 HelloService 3. 4.的 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. ifsServiceManagernull 7. returnsServiceManager 8. 9. 10. //Findtheservicemanager 11. sServiceManagerServiceManagerNative.asInterfaceBinderInternal.ge tContextObject 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 文件中:view plain 1. publicclassBinderInternal 2. ...... 3. / 4. Returntheglobalquotcontextobjectquotofthesystem.Thisisusually 5. animplementationofIServiceManagerwhichyoucanusetofind 6. otherservices. 7. / 8. publicstaticfinalnativeIBindergetContextObject 9. 10. ...... 11. 这里可以看出,BinderInternal.getContextObject 是一个 JNI 方法,它实现在frameworks/base/core/jni/
android_util_Binder.cpp 文件中:view plain 1. staticjobjectandroid_os_BinderInternal_getContextObjectJNIEnvenvjobje ctclazz 2. 3. spltIBindergtbProcessState::self‐gtgetContextObjectNULL 4. returnjavaObjectForIBinderenvb 5. 这里看到我们熟悉的 ProcessState::self-gtgetContextObject 函数,具体可以参考
Android 系统进程间通信(IPC)机制 Binder 中的 Server 和 Client 获得Service Manager 接口之路一文。
ProcessState::self-gtgetContextObject 函数返回一个 BpBinder 对象,它的句柄值是 0,即下面语句:view plain 1. spltIBindergtbProcessState::self‐gtgetContextObjectNULL 相当于是:view plain 1. spltIBindergtbnewBpBinder0 接着调用 javaObjectForIBinder 把这个 BpBinder 对象转换成一个BinderProxy 对象:view plain 1. jobjectjavaObjectForIBinderJNIEnvenvconstspltIBindergtampval 2. 3. ifvalNULLreturnNULL 4. 5. ifval‐gtcheckSubclassampgBinderOffsets 6. //Oneofourown 7. jobjectobjectstatic_castltJavaBBindergtval.get‐gtobject 8. //printfquotobjectForBinderp:itsourownpnquotval.getobject 9. returnobject 10. 11. 12. //Fortherestofthefunctionwewillholdthislocktoserialize 13. //looking/creationofJavaproxiesfornativeBinderproxies. 14. AutoMutex_lmProxyLock 15. 16. //Someoneelses...doweknowaboutit 17. jobjectobjectjobjectval‐gtfindObjectampgBinderProxyOffsets 18. ifobjectNULL 19. jobjectresenv‐gtCallObjectMethodobjectgWeakReferenceOffsets.mG et 20. ifresNULL 21. LOGVquotobjectForBinderp:foundexistingpnquotval.getres 22. returnres 23. 24. LOGVquotProxyobjectpofIBinderpnolongerinworkingsetquotob jectval.get 25.
android_atomic_decampgNumProxyRefs 26. val‐gtdetachObjectampgBinderProxyOffsets 27. env‐gtDeleteGlobalRefobject 28. 29. 30. objectenv‐gtNewObjectgBinderProxyOffsets.mClassgBinderProxyOffsets. mConstructor 31. ifobjectNULL 32. LOGVquotobjectForBinderp:creatednewpnquotval.getobject 33. //Theproxyholdsareferencetothenativeobject. 34. env‐gtSetIntFieldobjectgBinderProxyOffsets.mObjectintval.get 35. val‐gtincStrongobject 36. 37. //Thenativeobjectneedstoholdaweakreferencebacktothe 38. //proxysowecanretrievethesameproxyifitisstillactive. 39. jobjectrefObjectenv‐gtNewGlobalRef 40. env‐gtGetObjectFieldobjectgBinderProxyOffsets.mSelf 41. val‐gtattachObjectampgBinderProxyOffsetsrefObject 42. jnienv_to_javavmenvproxy_cleanup 43. 44. //Notethatanewobjectreferencehasbeencreated. 45.
android_atomic_incampgNumProxyRefs 46. incRefsCreatedenv 47. 48. 49. returnobject 50. 在介绍这个函数之前,先来看两个变量 gBinderOffsets 和gBinderProxyOffsets 的定义。
先看 gBinderOffsets 的定义:view plain 1. staticstructbindernative_offsets_t 2. 3. //Classstate. 4. jclassmClass 5. jmethodIDmExecTransact 6. 7. //Objectstate. 8. jfieldIDmObject 9. 10. gBinderOffsets 简单来说,gBinderOffsets 变量是用来记录上面第二个类图中的 Binder 类的相关信息的,它是在注册 Binder 类的 JNI 方法的 int_register_
android_os_Binder函数初始化的:view plain 1. constcharconstkBinderPathNamequotandroid/os/Binderquot 2. 3. staticintint_register_
android_os_BinderJNIEnvenv 4. 5. jclassclazz 6. 7. clazzenv‐gtFindClasskBinderPathName 8. LOG_FATAL_IFclazzNULLquotUnabletofindclassandroid.os.Binderquot 9. 10. gBinderOffsets.mClassjclassenv‐gtNewGlobalRefclazz 11. gBinderOffsets.mExecTransact 12. env‐gtGetMethodIDclazzquotexecTransactquotquotIIIIZquot 13. assertgBinderOffsets.mExecTransact 14. 15. gBinderOffsets.mObject 16. env‐gtGetFieldIDclazzquotmObjectquotquotIquot 17. assertgBinderOffsets.mObject 18. 19. returnAndroidRuntime::registerNativeMethods 20. envkBinderPathName 21. gBinderMethodsNELEMgBinderMethods 22. 再来看 gBinderProxyOffsets 的定义:view plain 1. staticstructbinderproxy_offsets_t 2. 3. //Classstate. 4. jclassmClass 5. jmethodIDmConstructor 6. jmethodIDmSendDeathNotice 7. 8. //Objectstate. 9. jfieldIDmObject 10. jfieldIDmSelf 11. 12. gBinderProxyOffsets 简单来说,gBinderProxyOffsets 是用来变量是用来记录上面第一个图中的BinderProxy 类的相关信息的,它是在注册 BinderProxy 类的 JNI 方法的int_register_
android_os_BinderProxy 函数初始化的:view plain 1. constcharconstkBinderProxyPathNamequotandroid/os/BinderProxyquot 2. 3. staticintint_register_
android_os_BinderProxyJNIEnvenv 4. 5. jclassclazz 6. 7. clazzenv‐gtFindClassquotjava/lang/ref/WeakReferencequot 8. LOG_FATAL_IFclazzNULLquotUnabletofindclassjava.lang.ref.WeakRefe rencequot 9. gWeakReferenceOffsets.mClassjclassenv‐gtNewGlobalRefclazz 10. gWeakReferenceOffsets.mGet 11. env‐gtGetMethodIDclazzquotgetquotquotLjava/lang/Objectquot 12. assertgWeakReferenceOffsets.mGet 13. 14. clazzenv‐gtFindClassquotjava/lang/Errorquot 15. LOG_FATAL_IFclazzNULLquotUnabletofindclassjava.lang.Errorquot 16. gErrorOffsets.mClassjclassenv‐gtNewGlobalRefclazz 17. 18. clazzenv‐gtFindClasskBinderProxyPathName 19. LOG_FATAL_IFclazzNULLquotUnabletofindclassandroid.os.BinderProxy quot 20. 21. gBinderProxyOffsets.mClassjclassenv‐gtNewGlobalRefclazz 22. gBinderProxyOffsets.mConstructor 23. env‐gtGetMethodIDclazzquotltinitgtquotquotVquot 24. assertgBinderProxyOffsets.mConstructor 25. gBinderProxyOffsets.mSendDeathNotice 26. env‐gtGetStaticMethodIDclazzquotsendDeathNoticequotquotLandroid/os/IBi nderDeathRecipientVquot 27. assertgBinderProxyOffsets.mSendDeathNotice 28. 29. gBinderProxyOffsets.mObject 30. env‐gtGetFieldIDclazzquotmObjectquotquotIquot 31. assertgBinderProxyOffsets.mObject 32. gBinderProxyOffsets.mSelf 33. env‐gtGetFieldIDclazzquotmSelfquotquotLjava/lang/ref/WeakReferencequot 34. assertgBinderProxyOffsets.mSelf 35. 36. returnAndroidRuntime::registerNativeMethods 37. envkBinderProxyPathName 38. gBinderProxyMethodsNELEMgBinderProxyMethods 39. 回到前面的 javaObjectForIBinder 函数中,下面这段代码:view plain 1. ifval‐gtcheckSubclassampgBinderOffsets 2. //Oneofourown 3. jobjectobjectstatic_castltJavaBBindergtval.get‐gtobject 4. //printfquotobjectForBinderp:itsourownpnquotval.getobject 5. returnobject 6. 前面说过,这里传进来的参数是一个 BpBinder 的指针,而BpBinder::checkSubclass 继承于父类 IBinder::checkSubclass,它什么也不做就返回 false。
于是函数继续往下执行:view plain 1. jobjectobjectjobjectval‐gtfindObjectampgBinderProxyOffsets 由于这个 BpBinder 对象是第一创建,它里面什么对象也没有,因此,这里返回的 object 为 NULL。
于是函数又继续往下执行:view plain 1. objectenv‐gtNewObjectgBinderProxyOffsets.mClassgBinderProxyOffsets.mCon structor 这里,就创建了一个 BinderProxy 对象了。
创建了之后,要把这个 BpBinder对象和这个 BinderProxy 对象关联起来:view plain 1. env‐gtSetIntFieldobjectgBinderProxyOffsets.mObjectintval.get 就是通过 BinderProxy.mObject 成员变量来关联的了,BinderProxy.mObject成员变量记录了这个 BpBinder 对象的地址。
接下去,还要把它放到 BpBinder 里面去,下次就要使用时,就可以在上一步调用 BpBinder::findObj 把它找回来了:view plain 1. val‐gtattachObjectampgBinderProxyOffsetsrefObject 2. jnienv_to_javavmenvproxy_cleanup 最后,就把这个 BinderProxy 返回到
android_os_BinderInternal_getContextObject 函数,最终返回到最开始的ServiceManager.getIServiceManager 函数中来了,于是,我们就获得一个BinderProxy 对象了。
回到 ServiceManager.getIServiceManager 中,从下面语句返回:view plain 1. sServiceManagerServiceManagerNative.asInterfaceBinderInternal.getContext Object 相当于是:view plain 1. sServiceManagerServiceManagerNative.asInterfacenewBinderProxy 接下去就是调用 ServiceManagerNative.asInterface 函数了,这个函数定义在frameworks/base/core/java/
android/os/ServiceManagerNative.java 文件中:view plain 1. publicabstractclassServiceManagerNative...... 2. 3. ...... 4. staticpublicIServiceManagerasInterfaceIBinderobj 5. 6. ifobjnull 7. returnnull 8. 9. IServiceManagerin 10. IServiceManagerobj.queryLocalInterfacedescriptor 11. ifinnull 12. returnin 13. 14. 15. returnnewServiceManagerProxyobj 16. 17. ...... 18. 这里的参数 obj 是一个 BinderProxy 对象,它的 queryLocalInterface 函数返回 null。
因此,最终以这个 BinderProxy 对象为参数创建一个 ServiceManagerProxy对象。
返回到 ServiceManager.getIServiceManager 中,从下面语句返回:view plain 1. sServiceManagerServiceManagerNative.asInterfacenewBinderProxy 就相当于是:view plain 1. sServiceManagernewServiceManagerProxynewBinderProxy 于是,我们的目标终于完成了。
总结一下,就是在 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. 3. interfaceIHelloService 4. 5. voidsetValintval 6. intgetVal 7. 这个服务接口很简单,只有两个函数,分别用来读写硬件寄存器。
注意,这是一个 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.Binderimplementsa ndroid.os.IHelloService 10. 11. privatestaticfinaljava.lang.StringDESCRIPTORquotandroid.os.IHell oServicequot 12. /Constructthestubatattachittotheinterface./ 13. publicStub 14. 15. this.attachInterfacethisDESCRIPTOR 16. 17. 18. / 19. CastanIBinderobjectintoanandroid.os.IHelloServiceinterface 20. generatingaproxyifneeded. 21. / 22. publicstaticandroid.os.IHelloServiceasInterfaceandroid.os.IBinde robj 23. 24. ifobjnull 25. returnnull26. 27.
android.os.IInterfaceiinandroid.os.IInterfaceobj.queryLoca lInterfaceDESCRIPTOR28. ifiinnullampampiininstanceofandroid.os.IHelloService29. returnandroid.os.IHelloServiceiin30. 31. returnnewandroid.os.IHelloService.Stub.Proxyobj32. 33.34. publicandroid.os.IBinderasBinder35. 36. returnthis37. 38.39. Override40. publicbooleanonTransactintcodeandroid.os.Parceldataandroid. os.Parcelrep.