【Android源码 栏目提醒】:网学会员,鉴于大家对Android源码 十分关注,论文会员在此为大家搜集整理了“Android系统的Binder机制之三——服务代理对象(2) - 综合课件”一文,供大家参考学习!
Android系统的Binder机制之三——服务代理对象2 1 / 10
Android系统的Binder机制之三——服务代理对象2 上文《
Android系统的Binder机制之二——服务代理对象1》我们学习了进程的C/C层面的服务代理对象BpBinder和Binder底层处理方式。
本文我们将深入分析一下在进程的Java层面服务代理对象的创建和使用。
Android进程的C/C层面和Java层
Android中程序大部分都是java开发底层通过JNI调用C/C的代码。
这样一个程序就分为了两个层面C/C层面和Java层面。
运行状态下我们说它们都在一个进程之中拥有相同的进程属性UIDGID等等。
Binder客户程序的C/C层面的对象和原理我们在上文《
Android系统的Binder机制之二——服务代理对象1》已经学习。
下面我们将介绍客户程序怎样在Java层面通过JNI调用底层C/C代码的创建服务代理。
ServiceManager类型和对象 我在《
Android系统的Binder机制之一——Service Manager》中介绍过客户端要想获得服务代理首先要向ServiceManager查询Service。
在Java层面也是这样所以我们首先分析Java层面ServiceManager类。
Android系统的Binder机制之三——服务代理对象2 2 / 10 我们通过查看ServiceManager的
源码我们发现ServiceManager类型也是一个Singleton类型。
所有的方法都是静态方法所有静态方法都是访问它的IServiceManager类型的静态变量sServiceManager定义如下 1: private static IServiceManager sServiceManager 所以可以理解ServiceManager就是IServiceManager对象的一个代理。
为创建和访问这个变量都是通过ServiceManager的getIServiceManager方法定义如下 1: private static IServiceManager getIServiceManager 2: if sServiceManager null 3: return sServiceManager 4: 5: 6: // Find the service manager 7: sServiceManager ServiceManagerNative.asInterfaceBinderInternal.getContextObject 8: return sServiceManager 9: 通过上面的代码非常清晰的告诉我们ServiceManager类型是一个Singleton类型。
现在我们主要研究sServiceManager对象怎样创建的。
如下代码创建IServiceManager对象 1: sServiceManager ServiceManagerNative.asInterfaceBinderInternal.getContextObject 我们首先查看BinderInternal类的getContextObject方法的代码发现是Native代码哈哈有终于到达C/C层面了我们已经熟悉了对应的代码为
android_util_binder.cppAndroid系统的Binder机制之三——服务代理对象2 3 / 10 中的
android_os_BinderInternal_getContextObject函数代码如下 1: static jobject
android_os_BinderInternal_getContextObjectJNIEnv env jobject clazz 2: 3: sp b ProcessState::self-getContextObjectNULL 4: return javaObjectForIBinderenv b 5: 终于看到我们上文《
Android系统的Binder机制之二——服务代理对象1》介绍过的ProcessState对象了我们再去查看ProcessState对象的getContextObject方法代码如下 1: sp ProcessState::getContextObjectconst sp caller 2: 3: if supportsProcesses 4: return getStrongProxyForHandle0 5: else 6: return getContextObjectString16default caller 7: 8: 我们看到在当前进程的ProcessState对象其实是调用getStrongProxyForHandle方法来创建binder句柄为0的服务代理对象——BpBinder对象我们在《
Android系统的Binder机制之一——Service Manager》提到过ServiceManager的binder句柄是一个闻名句柄0。
上文《
Android系统的Binder机制之二——服务代理对象1》
Android系统的Binder机制之三——服务代理对象2 4 / 10 已经介绍过ProcessState对象的getStrongProxyForHandle方法这里就不多说了。
我们可以看出Java调用C/C创建一个服务代理对象BpBinder在查看BpBinder的定义我们发现继承自IBinder接口然后在
android_util_binder.cpp中的方法
android_os_BinderInternal_getContextObject中把C/C层面的IBinder对象封装成Java层面的IBinder对象。
具体实现可以查看上文的
android_os_BinderInternal_getContextObject方法。
至此我们已经清楚BinderInternal.getContextObject返回的是ServiceManager的服务代理对象——BpBinder对象。
那么ServiceManagerNative类的静态方法asInterface做什么用呢我们还是通过代码来分析在ServiceManagerNative.java中asInterface的代码如下 1: static public IServiceManager asInterfaceIBinder obj 2: 3: if obj null 4: return null 5: 6: IServiceManager in 7: IServiceManagerobj.queryLocalInterfacedescriptor 8: if in null 9: return in 10: 11: 12: return new ServiceManagerProxyobj 13:
Android系统的Binder机制之三——服务代理对象2 5 / 10 将会用IBinder对象创建一个ServiceManagerProxy对象ServiceManagerProxy类型继承了IServiceManager接口所以asInterface方法最终目的是用一个IBinder对象创建一个IServiceManager对象。
为什么要用IBinder对象创建一个IServiceManager对象呢通过ServiceManager的代理对象——IBinder对象BpBinder对象应该可以直接请求ServiceManager中的服务了啊我们在前文《
Android系统的Binder机制之二——服务代理对象1》简单介绍了一下IBinder类型客户端通过transact方法向Service发送请求客户端的onTransact被调用处理客户端的请求请求通过请求代码来区分。
具体请参考
Android手册。
如果客户端直接用调用ServiceManager的代理对象的IBinder接口那么客户端必须要记住所有请求的请求代码对客户端来说不太友好。
所以在ServiceManagerNative类中就把ServiceManager的代理对象——IBinder对象BpBinder对象封装成ServiceManagerProxy对象暴露给客户程序一个IServiceManager接口这样IServiceManager对象将会代理客户程序发往ServiceManager的代理对象的请求。
并且是调用IServiceManager对象的方法来给ServiceManager发送请求这样对客户程序来讲和本地的函数调用是一致的接口
Android系统的Binder机制之三——服务代理对象2 6 / 10 非常友好。
比如我们客户程序需要调用IServiceManager的getService方法来查询一个ServiceServiceManagerProxy实现代码如下 1: public IBinder getServiceString name throws RemoteException 2: Parcel data Parcel.obtain 3: Parcel reply Parcel.obtain 4: data.writeInterfaceTokenIServiceManager.descriptor 5: data.writeStringname 6: mRemote.transactGET_SERVICE_TRANSACTION data reply 0 7: IBinder binder reply.readStrongBinder 8: reply.recycle 9: data.recycle 10: return binder 11: 我们可以非常清晰的看到ServiceManagerProxy对象将客户程序的请求转换成对ServiceManager代理对象——IBinder对象BpBinder对象的调用。
后文我们将会详细介绍怎样通过IServiceManager查询和获得一个系统Service代理对象。
到这里我们已经分析完了ServiceManager的Singleton对象——sServiceManager的创建。
如果有不清楚的地方请查看代码。
查询和获得Service代理对象 客户程序通过调用ServiceManager类型的静态方法asInterface获得了IServiceManager对象但是最终目的一般都是要查询和获得其他的Service一般都是要调用
Android系统的Binder机制之三——服务代理对象2 7 / 10 IServiceManager的getService方法向ServiceManager获得其他的Service。
比如 1: IBinder b ServiceManager.getServiceContext.NETWORKMANAGEMENT_SERVICE 上面的代码中就是调用ServiceManager的静态方法获得网络管理服务代理对象。
我们顺藤摸瓜看看系统是怎样生成这个Service代理对象的。
这里只是简单说明一下调用顺序详细过程请查看
源码。
1、调用ServiceManager.java中的ServiceManager静态方法getService。
2、调用ServiceManagerNative.java中的ServiceManagerProxy方法getService。
代码如下 1: public IBinder getServiceString name throws RemoteException 2: Parcel data Parcel.obtain 3: Parcel reply Parcel.obtain 4: data.writeInterfaceTokenIServiceManager.descriptor 5: data.writeStringname 6: mRemote.transactGET_SERVICE_TRANSACTION data reply 0 7: IBinder binder reply.readStrongBinder 8: reply.recycle 9: data.recycle 10: return binder 11: 请注意IBinder的transact方法是同步方法本例中ServiceManager处理完成请求之后才会返回我们可以看出调用transact之后调用reply.readStrongBinder来读取IBinder对象。
Android系统的Binder机制之三——服务代理对象2 8 / 10 3、查看Parcel.java中的readStrongBinder方法发现是Native方法将会调用到C/C的代码。
4、查看
android_util_binder.cpp中的
android_os_Parcel_readStrongBinder函数。
代码如下 1: static jobject
android_os_Parcel_readStrongBinderJNIEnv env jobject clazz 2: 3: Parcel parcel parcelForJavaObjectenv clazz 4: if parcel NULL 5: return javaObjectForIBinderenv parcel-readStrongBinder 6: 7: return NULL 8: parcel-readStrongBinder将会产生一个IBinder对象。
5、查看Parcel.cpp中Parcel的方法readStrongBinder。
代码如下 1: sp Parcel::readStrongBinder const 2: 3: sp val 4: unflatten_binderProcessState::self this val 5: return val 6: 6、查看Parcel.cpp中Parcel的方法unflatten_binder。
代码如下 1: status_t unflatten_binderconst sp proc 2: const Parcel in sp out 3: 4: const flat_binder_object flat in.readObjectfalse 5: 6: if flat
Android系统的Binder机制之三——服务代理对象2 9 / 10 7: switch flat-type 8: case BINDER_TYPE_BINDER: 9: out static_castflat-cookie 10: return finish_unflatten_binderNULL flat in 11: case BINDER_TYPE_HANDLE: 12: out proc-getStrongProxyForHandleflat-handle 13: return finish_unflatten_binder 14: static_castout-get flat in 15: 16: 17: return BAD_TYPE 18: 终于看到调用我们的老朋友ProcessState对象的getStrongProxyForHandle方法了这样将会创建一个BpBinder对象然后该BpBinder对象将会被转换成IBinder对象返回给Java层。
7、Java层为了用使用Service方便可以把Service代理对象——BpBinder对象IBinder对象封装成一个对客户程序友好的代理对象就如前面ServiceManagerProxy所示那样。
8、用户程序就可以通过该代理对象访问相应Service了。
通过所述我们了解了Service代理对象在Java层的创建和使用。
Android系统的Binder机制博大精深我在本文中很多方面都是蜻蜓点水如果想深入学习请参阅
Android的
源码。
参考资料
Android系统的Binder机制之三——服务代理对象2 10 / 10
上一篇:
[Android项目
下一篇:
个人哪些方面的情况值得你在简历里做介绍?