Binder机制详解程序员

Binder系列7—framework层分析

2018-04-04  本文已影响102人  十年开发程序员

一、概述

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

上一篇下一篇

猜你喜欢

热点阅读