Binder系列7—framework层分析
一、概述
1.1 Binder架构
binder在framework层,采用JNI技术来调用native(C/C++)层的binder架构,从而为上层应用程序提供服务。 看过binder系列之前的文章,我们知道native层中,binder是C/S架构,分为Bn端(Server)和Bp端(Client)。对于java层在命名与架构上非常相近,同样实现了一套IPC通信架构。
图解:
图中红色代表整个framework层 binder架构相关组件;
Binder类代表Server端,BinderProxy类代码Client端;
图中蓝色代表Native层Binder架构相关组件;
上层framework层的Binder逻辑是建立在Native层架构基础之上的,核心逻辑都是交予Native层方法来处理。
framework层的ServiceManager类与Native层的功能并不完全对应,framework层的ServiceManager类的实现最终是通过BinderProxy传递给Native层来完成的,后面会详细说明。
1.2 Binder类图
下面列举framework的binder类关系图
图解:(图中浅蓝色都是Interface,其余都是Class)
ServiceManager:通过getIServiceManager方法获取的是ServiceManagerProxy对象; ServiceManager的addService, getService实际工作都交由ServiceManagerProxy的相应方法来处理;
ServiceManagerProxy:其成员变量mRemote指向BinderProxy对象,ServiceManagerProxy的addService, getService方法最终是交由mRemote来完成。
ServiceManagerNative:其方法asInterface()返回的是ServiceManagerProxy对象,ServiceManager便是借助ServiceManagerNative类来找到ServiceManagerProxy;
Binder:其成员变量mObject和方法execTransact()用于native方法
BinderInternal:内部有一个GcWatcher类,用于处理和调试与Binder相关的垃圾回收。
IBinder:接口中常量FLAG_ONEWAY:客户端利用binder跟服务端通信是阻塞式的,但如果设置了FLAG_ONEWAY,这成为非阻塞的调用方式,客户端能立即返回,服务端采用回调方式来通知客户端完成情况。另外IBinder接口有一个内部接口DeathDecipient(死亡通告)。
1.3 Binder类分层
整个Binder从kernel至,native,JNI,Framework层所涉及的全部类
二、初始化
在Android系统开机过程中,Zygote启动时会有一个虚拟机注册过程,该过程调用AndroidRuntime::startReg方法来完成jni方法的注册。
2.1 startReg
==> AndroidRuntime.cpp
注册JNI方法,其中gRegJNI是一个数组,记录所有需要注册的jni方法,其中有一项便是REG_JNI(register_android_os_Binder),下面说说register_android_os_Binder过程。
2.2 register_android_os_Binder
==> android_util_Binder.cpp
2.3 注册Binder
==> android_util_Binder.cpp
注册 Binder类的jni方法,其中:
FindClassOrDie(env, kBinderPathName) 基本等价于 env->FindClass(kBinderPathName)
MakeGlobalRefOrDie() 等价于 env->NewGlobalRef()
GetMethodIDOrDie() 等价于 env->GetMethodID()
GetFieldIDOrDie() 等价于 env->GeFieldID()
RegisterMethodsOrDie() 等价于 Android::registerNativeMethods();
(1)gBinderOffsets
gBinderOffsets是全局静态结构体(struct),定义如下:
gBinderOffsets保存了Binder.java类本身以及其成员方法execTransact()和成员属性mObject,这为JNI层访问Java层提供通道。另外通过查询获取Java层 binder信息后保存到gBinderOffsets,而不再需要每次查找binder类信息的方式能大幅度提高效率,是由于每次查询需要花费较多的CPU时间,尤其是频繁访问时,但用额外的结构体来保存这些信息,是以空间换时间的方法。
(2)gBinderMethods
通过RegisterMethodsOrDie(),将为gBinderMethods数组中的方法建立了一一映射关系,从而为Java层访问JNI层提供通道。
总之,int_register_android_os_Binder方法的主要功能:
通过gBinderOffsets,保存Java层Binder类的信息,为JNI层访问Java层提供通道;
通过RegisterMethodsOrDie,将gBinderMethods数组完成映射关系,从而为Java层访问JNI层提供通道。
也就是说该过程建立了Binder类在Native层与framework层之间的相互调用的桥梁。
2.4 注册BinderInternal
==> android_util_Binder.cpp
注册BinderInternal类的jni方法,gBinderInternalOffsets保存了BinderInternal的forceBinderGc()方法。
下面是BinderInternal类的JNI方法注册:
该过程其【2.3】非常类似,也就是说该过程建立了是BinderInternal类在Native层与framework层之间的相互调用的桥梁。
2.5 注册BinderProxy
==> android_util_Binder.cpp
注册BinderProxy类的jni方法,gBinderProxyOffsets保存了BinderProxy的构造方法,sendDeathNotice(), mObject, mSelf, mOrgue信息。
下面BinderProxy类的JNI方法注册
该过程其【2.3】非常类似,也就是说该过程建立了是BinderProxy类在Native层与framework层之间的相互调用的桥梁。
三、注册服务
3.1 SM.addService
[-> ServiceManager.java]
先来看看getIServiceManager()过程,如下:
3.2 getIServiceManager
[-> ServiceManager.java]
采用了单例模式获取ServiceManager getIServiceManager()返回的是ServiceManagerProxy(简称SMP)对象
3.2.1 getContextObject()
[-> android_util_binder.cpp]
BinderInternal.java中有一个native方法getContextObject(),JNI调用执行上述方法。
对于ProcessState::self()->getContextObject(),在获取ServiceManager的第3节已详细解决,即ProcessState::self()->getContextObject()等价于 new BpBinder(0);
3.2.2 javaObjectForIBinder
[-> android_util_binder.cpp]
根据BpBinder(C++)生成BinderProxy(Java)对象. 主要工作是创建BinderProxy对象,并把BpBinder对象地址保存到BinderProxy.mObject成员变量. 到此,可知ServiceManagerNative.asInterface(BinderInternal.getContextObject()) 等价于
3.3 SMN.asInterface
[-> ServiceManagerNative.java]
由此,可知ServiceManagerNative.asInterface(new BinderProxy()) 等价于new ServiceManagerProxy(new BinderProxy()). 为了方便,ServiceManagerProxy简称为SMP。
3.3.1 ServiceManagerProxy初始化
[-> ServiceManagerNative.java ::ServiceManagerProxy]
mRemote为BinderProxy对象,该BinderProxy对象对应于BpBinder(0),其作为binder代理端,指向native层大管家service Manager。
ServiceManager.getIServiceManager最终等价于new ServiceManagerProxy(new BinderProxy()),意味着【3.1】中的getIServiceManager().addService(),等价于SMP.addService().
framework层的ServiceManager的调用实际的工作确实交给SMP的成员变量BinderProxy;而BinderProxy通过jni方式,最终会调用BpBinder对象;可见上层binder架构的核心功能依赖native架构的服务来完成的。
3.4 SMP.addService
[-> ServiceManagerNative.java ::ServiceManagerProxy]
3.5 writeStrongBinder(Java)
[-> Parcel.java]
3.5.1 android_os_Parcel_writeStrongBinder
[-> android_os_Parcel.cpp]
3.5.2 ibinderForJavaObject
[-> android_util_Binder.cpp]
根据Binde(Java)生成JavaBBinderHolder(C++)对象. 主要工作是创建JavaBBinderHolder对象,并把JavaBBinderHolder对象地址保存到Binder.mObject成员变量.
3.5.3 JavaBBinderHolder.get()
[-> android_util_Binder.cpp]
JavaBBinderHolder有一个成员变量mBinder,保存当前创建的JavaBBinder对象,这是一个wp类型的,可能会被垃圾回收器给回收,所以每次使用前,都需要先判断是否存在。
3.5.4 JavaBBinder初始化
==> [-> android_util_Binder.cpp]
创建JavaBBinder,该对象继承于BBinder对象。
data.writeStrongBinder(service)最终等价于parcel->writeStrongBinder(new JavaBBinder(env, obj));
3.6 writeStrongBinder(C++)
[-> parcel.cpp]
3.6.1 flatten_binder
[-> parcel.cpp]
将Binder对象扁平化,转换成flat_binder_object对象。
对于Binder实体,则cookie记录Binder实体的指针;
对于Binder代理,则用handle记录Binder代理的句柄;
关于localBinder,代码见Binder.cpp。
3.6.2 finish_flatten_binder
再回到小节3.4的addService过程,则接下来进入transact。
3.7 BinderProxy.transact
[-> Binder.java ::BinderProxy]
回到ServiceManagerProxy.addService,其成员变量mRemote是BinderProxy。transactNative经过jni调用,进入下面的方法
3.8 android_os_BinderProxy_transact
[-> android_util_Binder.cpp]
Java层的BinderProxy.transact()最终交由Native层的BpBinder::transact()完成。Native Binder的注册服务(addService)中有详细说明BpBinder执行过程。另外,该方法可抛出RemoteException。
3.9 小结
addService的核心过程:
四、获取服务
4.1 SM.getService
[-> ServiceManager.java]
关于getIServiceManager(),在前面小节3.2已经讲述了,等价于new ServiceManagerProxy(new BinderProxy())。 其中sCache = new HashMap()以hashmap格式缓存已组成的名称。请求获取服务过程中,先从缓存中查询是否存在,如果缓存中不存在的话,再通过binder交互来查询相应的服务。
4.2 SMP.getService
[-> ServiceManagerNative.java ::ServiceManagerProxy]
4.3 BinderProxy.transact
[-> Binder.java]
4.4 android_os_BinderProxy_transact
[-> android_util_Binder.cpp]
0