Binder 系统可以运行在Android Native环境,但在Java虚拟机中却运行不了。因此,要在Java环境中使用Binder通信,就需要调用一些JNI native函数(/android_runtime/android_util_Binder.cpp)
获取IServiceManager
ServiceManager.java文件管理着Java层的所有服务。如果要调用ServiceManager.java中的任何函数,都必须先获取到IserviceManager这个接口。
BinderInternal.getContextObject 是一个定义为android_os_BinderInternal_getContextObject的 JNI native函数。通过调用C++层的binder system, 它可以获取到一个IBinder(实际上它是指向C++层的BpServiceManager),然后通过调用javaObjectForIBinder,就可以创建一个java类,从而代替C++中的IBinder对象。
javaObjectForIBinder首先会判断这个object对象是service提供者还是service的使用者。在getIServiceManager中,这个object是一个服务使用者,因此它会new一个java BinderProxy object来取代C++环境中的IBinder object。
就这样,现在我们就有了个Java 的BinderProxy object。 ServiceManagerNative.asInterface将会在BinderProxy 对象中new一个ServiceManagerProxy。
因此,调用getIServiceManager将最终返回个ServiceManagerProxy实例。
创建Service
当创建Java service 对象(派生于Binder)时,将会调用init native函数android_os_Binder_init(请参考Binder.java)。在这里它会new一个JavaBBinderHoder,目前可能用不到,但在后面会派上用场。
添加Service RPC调用
任何Java层的service都应该调用IServiceManager.addService 这个API函数来注册自身的服务。IServiceManager.addService其实就等于ServiceManagerProxy.addService这个函数。
在调用ServiceManagerProxy.addService过程中,java中的service object会被写入到Parcel容器中,并最终调用到android_os_Parcel_writerStrongBinder这个Native函数。
android_os_Parcel_writeStrongBinder通过调用ibinderForJavaObject来产生一个JavaBBinderHolder object,它的功能相当于C++层的IBinder object。
JavaBBinderHolder将最终new一个JavaBBinder实例。
JavaBBinder object派生于BBinder。调用完ibinderForJavaObject之后,Android就已经在JAVA层的service类中创建了一个C++层的BBinder对象。
接着,ServiceManagerProxy会调用BinderProxy JNI native函数android_os_BinderProxy_transact来实现JAVA到C++之间的PRC调用。在这个函数中,C++中的IBinder object(实际上就是之前提到的BpServiceManager对象)对应于Java 中的BinderProxy,它原先保存在javaObjectForIBinder中。
到现在为止,Android已经可以把Java层的RPC调用发送到C++层了。RPC调用将会交由service_manager进程来处理。至于C++层的处理过程将不在本文的讨论范围之内,有兴趣的话可以参考作者关于C++层Binder 系统原理介绍的文章。
获取IsensorService服务
获取一个接口(interface)的唯一方式是通过调用IserviceManager.getService函数。过程类似于调用IServiceManager.addService。Java 的ServiceManagerProxy把RPC发送给C++层的BpServiceManager,BpServiceManager会把调用发送到service_manager进程。BpServiceManager会接着进行执行。返回的C++层的IBinder object实际上就是一个BpBinder实例。
接收到transact之后,ServiceManagerProxy会调用JNI native函数android_os_Parcel_readStrongBinder。这个函数会调用javaObjectForIBinder函数来为返回的C++ IBinder object创建一个Java 对象。
javaObjectForIBinder会判断object属于service提供者还是服务使用者。在这里,这个object对象是个服务使用者。因此,它会new一个Java BinderProxy object来代表C++中的IBinder object。这样,我们就获得了一个Java BinderProxy对象。接着,ISensorService.Stub.asInterface会在BinderProxy对象中new一个ISensorService.Stub.Proxy。
这样,我们就获得了一个ISensorService.Stub.Proxy实例。
ISensorService.reportAccurary RPC调用
这等同于调用ISensorService.Stub.Proxy.reportAccuracy。它的代码是通过aidl语言自动生成的。它调用BinderProxy 的JNI native函数android_os_BinderProxy_transact来把JAVA中的RPC调用派发到C++中。就这样,Android完成了JAVA到C++之间的RPC调用。
处理ISensorService.reportAccuracy RPC调用
RPC调用将由C++层的JavaBBinder object处理,JavaBBinder object会在调用IServiceManager.addService时创建。
JavaBBinder会通过JNI调用到Java层的函数。这个函数是Binder.executeTransact。
最终,Binder.executeTransact会调用到ISensorService.onTransact。ISensorService.onTransact会调用到SensorService.reportAccuracy来执行实际的工作。
原文转载地址:http://blog.chinaunix.net/space.php?uid=20564848&do=blog&id=73517
First written by Steve Guo, please keep the mark if forwarding.