Binder系列7—framework層分析

一、概述

1.1 Binder架構(gòu)

binder在framework層,采用JNI技術(shù)來調(diào)用native(C/C++)層的binder架構(gòu),從而為上層應(yīng)用程序提供服務(wù)。 看過binder系列之前的文章,我們知道native層中,binder是C/S架構(gòu),分為Bn端(Server)和Bp端(Client)。對于java層在命名與架構(gòu)上非常相近,同樣實(shí)現(xiàn)了一套IPC通信架構(gòu)。


圖解:

圖中紅色代表整個(gè)framework層 binder架構(gòu)相關(guān)組件;

Binder類代表Server端,BinderProxy類代碼Client端;

圖中藍(lán)色代表Native層Binder架構(gòu)相關(guān)組件;

上層framework層的Binder邏輯是建立在Native層架構(gòu)基礎(chǔ)之上的,核心邏輯都是交予Native層方法來處理。

framework層的ServiceManager類與Native層的功能并不完全對應(yīng),framework層的ServiceManager類的實(shí)現(xiàn)最終是通過BinderProxy傳遞給Native層來完成的,后面會詳細(xì)說明。

1.2 Binder類圖

下面列舉framework的binder類關(guān)系圖


圖解:(圖中淺藍(lán)色都是Interface,其余都是Class)

ServiceManager:通過getIServiceManager方法獲取的是ServiceManagerProxy對象; ServiceManager的addService, getService實(shí)際工作都交由ServiceManagerProxy的相應(yīng)方法來處理;

ServiceManagerProxy:其成員變量mRemote指向BinderProxy對象,ServiceManagerProxy的addService, getService方法最終是交由mRemote來完成。

ServiceManagerNative:其方法asInterface()返回的是ServiceManagerProxy對象,ServiceManager便是借助ServiceManagerNative類來找到ServiceManagerProxy;

Binder:其成員變量mObject和方法execTransact()用于native方法

BinderInternal:內(nèi)部有一個(gè)GcWatcher類,用于處理和調(diào)試與Binder相關(guān)的垃圾回收。

IBinder:接口中常量FLAG_ONEWAY:客戶端利用binder跟服務(wù)端通信是阻塞式的,但如果設(shè)置了FLAG_ONEWAY,這成為非阻塞的調(diào)用方式,客戶端能立即返回,服務(wù)端采用回調(diào)方式來通知客戶端完成情況。另外IBinder接口有一個(gè)內(nèi)部接口DeathDecipient(死亡通告)。

1.3 Binder類分層

整個(gè)Binder從kernel至,native,JNI,F(xiàn)ramework層所涉及的全部類


二、初始化

在Android系統(tǒng)開機(jī)過程中,Zygote啟動時(shí)會有一個(gè)虛擬機(jī)注冊過程,該過程調(diào)用AndroidRuntime::startReg方法來完成jni方法的注冊。

2.1 startReg

==> AndroidRuntime.cpp


注冊JNI方法,其中g(shù)RegJNI是一個(gè)數(shù)組,記錄所有需要注冊的jni方法,其中有一項(xiàng)便是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) 基本等價(jià)于 env->FindClass(kBinderPathName)

MakeGlobalRefOrDie() 等價(jià)于 env->NewGlobalRef()

GetMethodIDOrDie() 等價(jià)于 env->GetMethodID()

GetFieldIDOrDie() 等價(jià)于 env->GeFieldID()

RegisterMethodsOrDie() 等價(jià)于 Android::registerNativeMethods();

(1)gBinderOffsets

gBinderOffsets是全局靜態(tài)結(jié)構(gòu)體(struct),定義如下:


gBinderOffsets保存了Binder.java類本身以及其成員方法execTransact()和成員屬性mObject,這為JNI層訪問Java層提供通道。另外通過查詢獲取Java層 binder信息后保存到gBinderOffsets,而不再需要每次查找binder類信息的方式能大幅度提高效率,是由于每次查詢需要花費(fèi)較多的CPU時(shí)間,尤其是頻繁訪問時(shí),但用額外的結(jié)構(gòu)體來保存這些信息,是以空間換時(shí)間的方法。

(2)gBinderMethods


通過RegisterMethodsOrDie(),將為gBinderMethods數(shù)組中的方法建立了一一映射關(guān)系,從而為Java層訪問JNI層提供通道。

總之,int_register_android_os_Binder方法的主要功能:

通過gBinderOffsets,保存Java層Binder類的信息,為JNI層訪問Java層提供通道;

通過RegisterMethodsOrDie,將gBinderMethods數(shù)組完成映射關(guān)系,從而為Java層訪問JNI層提供通道。

也就是說該過程建立了Binder類在Native層與framework層之間的相互調(diào)用的橋梁。

2.4 注冊BinderInternal

==> android_util_Binder.cpp

注冊BinderInternal類的jni方法,gBinderInternalOffsets保存了BinderInternal的forceBinderGc()方法。

下面是BinderInternal類的JNI方法注冊:

該過程其【2.3】非常類似,也就是說該過程建立了是BinderInternal類在Native層與framework層之間的相互調(diào)用的橋梁。

2.5 注冊BinderProxy

==> android_util_Binder.cpp

注冊BinderProxy類的jni方法,gBinderProxyOffsets保存了BinderProxy的構(gòu)造方法,sendDeathNotice(), mObject, mSelf, mOrgue信息。

下面BinderProxy類的JNI方法注冊

該過程其【2.3】非常類似,也就是說該過程建立了是BinderProxy類在Native層與framework層之間的相互調(diào)用的橋梁。

三、注冊服務(wù)

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中有一個(gè)native方法getContextObject(),JNI調(diào)用執(zhí)行上述方法。

對于ProcessState::self()->getContextObject(),在獲取ServiceManager的第3節(jié)已詳細(xì)解決,即ProcessState::self()->getContextObject()等價(jià)于?new BpBinder(0);

3.2.2 javaObjectForIBinder

[-> android_util_binder.cpp]


根據(jù)BpBinder(C++)生成BinderProxy(Java)對象. 主要工作是創(chuàng)建BinderProxy對象,并把BpBinder對象地址保存到BinderProxy.mObject成員變量. 到此,可知ServiceManagerNative.asInterface(BinderInternal.getContextObject()) 等價(jià)于


3.3 SMN.asInterface

[-> ServiceManagerNative.java]


由此,可知ServiceManagerNative.asInterface(new BinderProxy()) 等價(jià)于new ServiceManagerProxy(new BinderProxy()). 為了方便,ServiceManagerProxy簡稱為SMP。

3.3.1 ServiceManagerProxy初始化

[-> ServiceManagerNative.java ::ServiceManagerProxy]


mRemote為BinderProxy對象,該BinderProxy對象對應(yīng)于BpBinder(0),其作為binder代理端,指向native層大管家service Manager。

ServiceManager.getIServiceManager最終等價(jià)于new ServiceManagerProxy(new BinderProxy()),意味著【3.1】中的getIServiceManager().addService(),等價(jià)于SMP.addService().

framework層的ServiceManager的調(diào)用實(shí)際的工作確實(shí)交給SMP的成員變量BinderProxy;而BinderProxy通過jni方式,最終會調(diào)用BpBinder對象;可見上層binder架構(gòu)的核心功能依賴native架構(gòu)的服務(wù)來完成的。

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]


根據(jù)Binde(Java)生成JavaBBinderHolder(C++)對象. 主要工作是創(chuàng)建JavaBBinderHolder對象,并把JavaBBinderHolder對象地址保存到Binder.mObject成員變量.

3.5.3 JavaBBinderHolder.get()

[-> android_util_Binder.cpp]


JavaBBinderHolder有一個(gè)成員變量mBinder,保存當(dāng)前創(chuàng)建的JavaBBinder對象,這是一個(gè)wp類型的,可能會被垃圾回收器給回收,所以每次使用前,都需要先判斷是否存在。

3.5.4 JavaBBinder初始化

==> [-> android_util_Binder.cpp]


創(chuàng)建JavaBBinder,該對象繼承于BBinder對象。

data.writeStrongBinder(service)最終等價(jià)于parcel->writeStrongBinder(new JavaBBinder(env, obj));

3.6 writeStrongBinder(C++)

[-> parcel.cpp]


3.6.1 flatten_binder

[-> parcel.cpp]


將Binder對象扁平化,轉(zhuǎn)換成flat_binder_object對象。

對于Binder實(shí)體,則cookie記錄Binder實(shí)體的指針;

對于Binder代理,則用handle記錄Binder代理的句柄;

關(guān)于localBinder,代碼見Binder.cpp。


3.6.2 finish_flatten_binder


再回到小節(jié)3.4的addService過程,則接下來進(jìn)入transact。

3.7 BinderProxy.transact

[-> Binder.java ::BinderProxy]


回到ServiceManagerProxy.addService,其成員變量mRemote是BinderProxy。transactNative經(jīng)過jni調(diào)用,進(jìn)入下面的方法

3.8 android_os_BinderProxy_transact

[-> android_util_Binder.cpp]


Java層的BinderProxy.transact()最終交由Native層的BpBinder::transact()完成。Native Binder的注冊服務(wù)(addService)中有詳細(xì)說明BpBinder執(zhí)行過程。另外,該方法可拋出RemoteException。

3.9 小結(jié)

addService的核心過程:

四、獲取服務(wù)

4.1 SM.getService

[-> ServiceManager.java]


關(guān)于getIServiceManager(),在前面小節(jié)3.2已經(jīng)講述了,等價(jià)于new ServiceManagerProxy(new BinderProxy())。 其中sCache = new HashMap()以hashmap格式緩存已組成的名稱。請求獲取服務(wù)過程中,先從緩存中查詢是否存在,如果緩存中不存在的話,再通過binder交互來查詢相應(yīng)的服務(wù)。

4.2 SMP.getService

[-> ServiceManagerNative.java ::ServiceManagerProxy]


4.3 BinderProxy.transact

[-> Binder.java]

4.4 android_os_BinderProxy_transact

[-> android_util_Binder.cpp]


0

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容