Android跨進(jìn)程通信IPC整體內(nèi)容如下
- 1稽坤、Android跨進(jìn)程通信IPC之1——Linux基礎(chǔ)
- 2丈甸、Android跨進(jìn)程通信IPC之2——Bionic
- 3糯俗、Android跨進(jìn)程通信IPC之3——關(guān)于"JNI"的那些事
- 4、Android跨進(jìn)程通信IPC之4——AndroidIPC基礎(chǔ)1
- 4睦擂、Android跨進(jìn)程通信IPC之4——AndroidIPC基礎(chǔ)2
- 5得湘、Android跨進(jìn)程通信IPC之5——Binder的三大接口
- 6、Android跨進(jìn)程通信IPC之6——Binder框架
- 7祈匙、Android跨進(jìn)程通信IPC之7——Binder相關(guān)結(jié)構(gòu)體簡介
- 8忽刽、Android跨進(jìn)程通信IPC之8——Binder驅(qū)動(dòng)
- 9、Android跨進(jìn)程通信IPC之9——Binder之Framework層C++篇1
- 9夺欲、Android跨進(jìn)程通信IPC之9——Binder之Framework層C++篇2
- 10跪帝、Android跨進(jìn)程通信IPC之10——Binder之Framework層Java篇
- 11、Android跨進(jìn)程通信IPC之11——AIDL
- 12些阅、Android跨進(jìn)程通信IPC之12——Binder補(bǔ)充
- 13伞剑、Android跨進(jìn)程通信IPC之13——Binder總結(jié)
- 14、Android跨進(jìn)程通信IPC之14——其他IPC方式
- 15市埋、Android跨進(jìn)程通信IPC之15——感謝
本篇主要分析Binder在framework中Java層的框架黎泣,相關(guān)源碼
framework/base/core/java/android/os/
- IInterface.java
- IServiceManager.java
- ServiceManager.java
- ServiceManagerNative.java(包含內(nèi)部類ServiceManagerProxy)
framework/base/core/java/android/os/
- IBinder.java
- Binder.java(包含內(nèi)部類BinderProxy)
- Parcel.java
framework/base/core/java/com/android/internal/os/
- BinderInternal.java
framework/base/core/jni/
- AndroidRuntime.cpp
- android_os_Parcel.cpp
- android_util_Binder.cpp
鏈接如下:
一、概述
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)项郊。對(duì)于Java層在命令與架構(gòu)上非常相近,同時(shí)實(shí)現(xiàn)了一套IPC通信架構(gòu)斟赚。
(一)架構(gòu)圖
framework Binder架構(gòu)圖:
圖解:
- 圖中紫色色代表整個(gè)framework層binder相關(guān)組件着降,其中Binder代表Server端,BinderProxy代表Client端
- 圖中黑色代表Native層Binder架構(gòu)相關(guān)組件
- 上層framework層的Binder邏輯是建立在Native層架構(gòu)基礎(chǔ)上的拗军,核心邏輯都是交于Native層來處理
- framework層的ServiceManager類與Native層的功能并不完全對(duì)應(yīng)任洞,framework層的ServiceManager的實(shí)現(xiàn)對(duì)最終是通過BinderProxy傳遞給Native層來完成的。
(二)发侵、類圖
下面列舉framework的binder類的關(guān)系圖:
圖解:
其中藍(lán)色都是interface,其余都是Class
- ServiceManager:通過getIServiceManager方法獲取的是ServiceManagerProxy對(duì)象侈咕。ServiceMnager的addService(),getService()實(shí)際工作都交給ServiceManagerProxy的相應(yīng)方法來處理器紧。
- ServiceManagerProxy:其成員變量mRemote指向BinderProxy對(duì)象,ServiceManagerProxy的addService()楼眷,getService()方法最終是交給mRemote去完成铲汪。
- ServiceManagerNative:其方法asInterface()返回的是ServiceManagerProxy對(duì)象熊尉,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)部接口DeathDecipent(死亡通告)创南。
(三)、Binder類分層
整個(gè)Binder從kernel至native省核,JNI稿辙,F(xiàn)ramework層所涉及的全部類
Android應(yīng)用程序使用Java語言開發(fā),Binder框架自然也少不了在Java層提供接口气忠。前面的文章我們知道邻储,Binder機(jī)制在C++層有了完整的實(shí)現(xiàn)。因此Java層完全不用重復(fù)實(shí)現(xiàn)旧噪,而是通過JNI銜接C++層以復(fù)用其實(shí)現(xiàn)吨娜。
關(guān)于Binder類中 從Binder Framework層到C++層的銜接關(guān)系如下圖:
圖解:
- IInterface(interface) :供Java層Binder服務(wù)接口繼承的接口
- IBinder(interface):Java層IBinder類,提供了transaction方法來調(diào)用遠(yuǎn)程服務(wù)
- Binder(class):實(shí)現(xiàn)了IBinder接口淘钟,封裝了JNI的實(shí)現(xiàn)宦赠。Java層Binder服務(wù)的基類
- BInderProxy(class):實(shí)現(xiàn)了IBinder接口,封裝了JNI的實(shí)現(xiàn)日月。提供transac()方法調(diào)用遠(yuǎn)程服務(wù)
- JavaBBinderHolder(class) :內(nèi)部存儲(chǔ)了JavaBBinder
- JavaBBinder(class):將C++端的onTransact調(diào)用傳遞到Java端
- Parcel(class):Java層的數(shù)據(jù)包裝器袱瓮。
這里的IInterface,IBinder和C++層的兩個(gè)類是同名的爱咬。這個(gè)同名并不是巧合:它們不僅僅是同名尺借,它們所起到的作用,以及其中包含的接口幾乎都是一樣的精拟,區(qū)別僅僅是一個(gè)在C++層燎斩,一個(gè)在Java層而已。而且除了IInterface蜂绎,IBinder之外栅表,這里Binder與BinderProxy類也是與C++的類對(duì)應(yīng)的,下面列出了Java層和C++層類的對(duì)應(yīng)關(guān)系师枣。
C++層 | Java層 |
---|---|
IInterface | IInterface |
IBinder | IBinder |
BBinder | BBinder |
BpProxy | BpProxy |
Parcel | Parcel |
(四)怪瓶、JNI的銜接
JNI全稱是Java Native Interface,這個(gè)是由Java虛擬機(jī)提供的機(jī)制践美。這個(gè)機(jī)制使得natvie代碼可以和Java代碼相互通訊洗贰。簡單的來說就是:我們可以在C/C++端調(diào)用Java代碼找岖,也可以在Java端調(diào)用C/C++代碼。
關(guān)于JNI的詳細(xì)說明敛滋,可以參見Oracle的官方文檔:Java Native Interface 许布,這里就不詳細(xì)說明了。
實(shí)際上绎晃,在Android中很多的服務(wù)或者機(jī)制都是在C/C++層實(shí)現(xiàn)的蜜唾,想要將這些實(shí)現(xiàn)復(fù)用到Java層
就必須通過JNI進(jìn)行銜接。Android Opne Source Projcet(以后簡稱AOSP)在源碼中庶艾,/frameworks/base/core/jni/ 目錄下的源碼就是專門用來對(duì)接Framework層的JNI實(shí)現(xiàn)袁余。其實(shí)大家看一下Binder.java的實(shí)現(xiàn)就會(huì)發(fā)現(xiàn),這里面有不少的方法都是native 關(guān)鍵字修飾的落竹,并且沒有方法實(shí)現(xiàn)體泌霍,這些方法其實(shí)都是在C++中實(shí)現(xiàn)的。
以Binder為例:
1述召、Java調(diào)用C++層代碼
// Binder.java
public static final native int getCallingPid();
public static final native int getCallingUid();
public static final native long clearCallingIdentity();
public static final native void restoreCallingIdentity(long token);
public static final native void setThreadStrictModePolicy(int policyMask);
public static final native int getThreadStrictModePolicy();
public static final native void flushPendingCommands();
public static final native void joinThreadPool();
在 android_util_Binder.cpp文件中的下面的這段代碼朱转,設(shè)定了Java方法與C++方法對(duì)應(yīng)關(guān)系
//android_util_Binder 843行
static const JNINativeMethod gBinderMethods[] = {
{ "getCallingPid", "()I", (void*)android_os_Binder_getCallingPid },
{ "getCallingUid", "()I", (void*)android_os_Binder_getCallingUid },
{ "clearCallingIdentity", "()J", (void*)android_os_Binder_clearCallingIdentity },
{ "restoreCallingIdentity", "(J)V", (void*)android_os_Binder_restoreCallingIdentity },
{ "setThreadStrictModePolicy", "(I)V", (void*)android_os_Binder_setThreadStrictModePolicy },
{ "getThreadStrictModePolicy", "()I", (void*)android_os_Binder_getThreadStrictModePolicy },
{ "flushPendingCommands", "()V", (void*)android_os_Binder_flushPendingCommands },
{ "init", "()V", (void*)android_os_Binder_init },
{ "destroy", "()V", (void*)android_os_Binder_destroy },
{ "blockUntilThreadAvailable", "()V", (void*)android_os_Binder_blockUntilThreadAvailable }
};
這種對(duì)應(yīng)關(guān)系意味著:當(dāng)Binder.java中的getCallingPid()方法被調(diào)用的時(shí)候,真正的實(shí)現(xiàn)其實(shí)是android_os_Binder_getCallingPic积暖,當(dāng)getCallUid方法被調(diào)用的時(shí)候藤为,真正的實(shí)現(xiàn)其實(shí)是android_os_Binder_getCallingUid,其他類同夺刑。
然后我們?cè)倏匆幌耡ndroid_os_Binder_getCallingPid方法的實(shí)現(xiàn)就會(huì)發(fā)現(xiàn)缅疟,這里其實(shí)就是對(duì)街道了libbinder中了:
static jint android_os_Binder_getCallingPid(JNIEnv* env, jobject clazz)
{
return IPCThreadState::self()->getCallingPid();
}
2、C++層代碼調(diào)用Java代碼
上面看到了Java端代碼是如何調(diào)用libbinder中的C++方法的遍愿。那么相反的方向是如何調(diào)用的存淫?關(guān)鍵,libbinder中的** BBinder::onTransacts **是如何能能夠調(diào)用到Java中的Binder:: onTransact的沼填?
這段邏輯就是android_util_Binder.cpp中JavaBBinder::onTransact中處理的了桅咆。JavaBBinder是BBinder的子類,其類的結(jié)構(gòu)如下:
JavaBBinder:: onTransact關(guān)鍵代碼如下:
//android_util_Binder 247行
virtual status_t onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0)
{
JNIEnv* env = javavm_to_jnienv(mVM);
IPCThreadState* thread_state = IPCThreadState::self();
const int32_t strict_policy_before = thread_state->getStrictModePolicy();
jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,
code, reinterpret_cast<jlong>(&data), reinterpret_cast<jlong>(reply), flags);
...
}
注意這一段代碼:
jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,
code, reinterpret_cast<jlong>(&data), reinterpret_cast<jlong>(reply), flags);
這一行代碼其實(shí)是在調(diào)用mObject上offset為mExecTransact的方法坞笙。這里的幾個(gè)參數(shù)說明下:
- mObject指向了Java端的Binder對(duì)象
- gBinderOffsets.mExecTransact指向了Binder類的exectTransac方法
- data調(diào)用了exectTransac方法的參數(shù)
- code岩饼,data,reply薛夜,flag都是傳遞給調(diào)用方法execTransact參數(shù)
而JNIEnv.callBooleanMethod這個(gè)方法是由虛擬機(jī)實(shí)現(xiàn)的籍茧。即:虛擬機(jī)提供native方法來調(diào)用一個(gè)Java Object上方法。
這樣梯澜,就在C++層的JavaBBinder::onTransact中調(diào)用了Java層 Binder::execTransact方法寞冯。而在Binder::execTransact方法中,又調(diào)用了自身的onTransact方法,由此保證整個(gè)過程串聯(lián)起來吮龄。
二檬某、初始化
在Android系統(tǒng)開始過程中,Zygote啟東時(shí)會(huì)有一個(gè)"虛擬機(jī)注冊(cè)過程"螟蝙,該過程調(diào)用AndroidRuntime::startReg()方法來完成jni方法的注冊(cè)
1、startReg()函數(shù)
// frameworks/base/core/jni/AndroidRuntime.cpp 1440行
int AndroidRuntime::startReg(JNIEnv* env)
{
androidSetCreateThreadFunc((android_create_thread_fn) javaCreateThreadEtc);
env->PushLocalFrame(200);
//核心函數(shù) register_jni_procs() 注冊(cè)jni方法
if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {
env->PopLocalFrame(NULL);
return -1;
}
env->PopLocalFrame(NULL);
return 0;
}
注冊(cè) JNI方法民傻,其中g(shù)RegJNI是一個(gè)數(shù)組胰默,記錄所有需要注冊(cè)的jni方法,其中有一項(xiàng)便是REG_JNI(register_android_os_Binder)漓踢。
1.1 gRegJNI數(shù)組
REG_JNI(register_android_os_Binder)在 ** frameworks/base/core/jni/AndroidRuntime.cpp ** 的1312行牵署,大家自行去查看吧。
// frameworks/base/core/jni/AndroidRuntime.cpp 1296行喧半。
static const RegJNIRec gRegJNI[] = {
......
REG_JNI(register_android_os_SystemProperties),
// ***** 重點(diǎn)部分 *****
REG_JNI(register_android_os_Binder),
// ***** 重點(diǎn)部分 *****
REG_JNI(register_android_os_Parcel),
......
};
1.2 register_jni_procs() 函數(shù)
// frameworks/base/core/jni/AndroidRuntime.cpp 1283行
static int register_jni_procs(const RegJNIRec array[], size_t count, JNIEnv*env) {
for (size_t i = 0; i < count; i++) {
if (array[i].mProc(env) < 0) {
#ifndef NDEBUG
ALOGD("----------!!! %s failed to load\n", array[i].mName);
#endif
return -1;
}
}
return 0;
}
那讓我們繼續(xù)看
1.3 RegJNIRec數(shù)據(jù)結(jié)構(gòu)
#ifdef NDEBUG
#define REG_JNI(name) { name }
struct RegJNIRec {
int (*mProc)(JNIEnv*);
};
#else
#define REG_JNI(name) { name, #name }
struct RegJNIRec {
int (*mProc)(JNIEnv*);
const char* mName;
};
#endif
所以這里最終調(diào)用了register_android_os_Binder()函數(shù)奴迅,下面說說register_android_os_Binder過程。
2挺据、register_android_os_Binder()函數(shù)
// frameworks/base/core/jni/android_util_Binder.cpp 1282行
int register_android_os_Binder(JNIEnv* env)
{
// 注冊(cè)Binder類的 jin方法
if (int_register_android_os_Binder(env) < 0)
return -1;
// 注冊(cè) BinderInternal類的jni方法
if (int_register_android_os_BinderInternal(env) < 0)
return -1;
// 注冊(cè)BinderProxy類的jni方法
if (int_register_android_os_BinderProxy(env) < 0)
return -1;
...
return 0;
}
這里面主要是三個(gè)注冊(cè)方法
- int_register_android_os_Binder():注冊(cè)Binder類的JNI方法
- int_register_android_os_BinderInternal():注冊(cè)BinderInternal的JNI方法
- int_register_android_os_BinderProxy():注冊(cè)BinderProxy類的JNI方法
那么就讓我們依次研究下
2.1 int_register_android_os_Binder()函數(shù)
// frameworks/base/core/jni/android_util_Binder.cpp 589行
static int int_register_android_os_Binder(JNIEnv* env)
{
//kBinderPathName="android/os/Binder"取具,主要是查找kBinderPathName路徑所屬類
jclass clazz = FindClassOrDie(env, kBinderPathName);
//將Java層Binder類保存到mClass變量上
gBinderOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
//將Java層execTransact()方法保存到mExecTransact變量;
gBinderOffsets.mExecTransact = GetMethodIDOrDie(env, clazz, "execTransact", "(IJJI)Z");
//將Java層的mObject屬性保存到mObject變量中
gBinderOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");
//注冊(cè)JNI方法
return RegisterMethodsOrDie(env, kBinderPathName, gBinderMethods,
NELEM(gBinderMethods));
}
PS: 注冊(cè)Binder的JNI方法扁耐,其中:
- FindClassOrDie(env, kBinderPathName) 等于 env->FindClass(kBinderPathName)
- MakeGlobalRefOrDie() 等于 env->NewGlobalRef()
- GetMethodIDOrDie() 等于 env->GetMethodID()
- GetFieldIDOrDie() 等于 env->GeFieldID()
- RegisterMethodsOrDie() 等于 Android::registerNativeMethods();
上面代碼提到了gBinderOffsets暇检,它是一個(gè)什么東西?
2.1.1 gBinderOffsets:
gBinderOffsets是全局靜態(tài)結(jié)構(gòu)體(struct)婉称,定義如下:
// frameworks/base/core/jni/android_util_Binder.cpp 65行
static struct bindernative_offsets_t
{
// Class state.
//記錄 Binder類
jclass mClass;
// 記錄execTransact()方法
jmethodID mExecTransact;
// Object state.
// 記錄mObject屬性
jfieldID mObject;
} gBinderOffsets;
gBinderOffsets保存了Binder.java類本身以及其成員方法execTransact()和成員屬性mObject块仆,這為JNI層訪問Java層提供通道。另外通過查詢獲取Java層 binder信息后保存到gBinderOffsets王暗,而不再需要每次查找binder類信息的方式能大幅提高效率悔据,是由于每次查詢需要花費(fèi)較多的CPU時(shí)間,尤其是頻繁訪問時(shí)俗壹,但用額外的結(jié)構(gòu)體來保存這些信息科汗,是以空間換時(shí)間的方法。
2.1.2 gBinderMethods:
// frameworks/base/core/jni/android_util_Binder.cpp 843行
static const JNINativeMethod gBinderMethods[] = {
/* 名稱, 簽名, 函數(shù)指針 */
{ "getCallingPid", "()I", (void*)android_os_Binder_getCallingPid },
{ "getCallingUid", "()I", (void*)android_os_Binder_getCallingUid },
{ "clearCallingIdentity", "()J", (void*)android_os_Binder_clearCallingIdentity },
{ "restoreCallingIdentity", "(J)V", (void*)android_os_Binder_restoreCallingIdentity },
{ "setThreadStrictModePolicy", "(I)V", (void*)android_os_Binder_setThreadStrictModePolicy },
{ "getThreadStrictModePolicy", "()I", (void*)android_os_Binder_getThreadStrictModePolicy },
{ "flushPendingCommands", "()V", (void*)android_os_Binder_flushPendingCommands },
{ "init", "()V", (void*)android_os_Binder_init },
{ "destroy", "()V", (void*)android_os_Binder_destroy },
{ "blockUntilThreadAvailable", "()V", (void*)android_os_Binder_blockUntilThreadAvailable }
};
通過RegisterMethodsOrDie()策肝,將為gBinderMethods數(shù)組中的方法建立了一一映射關(guān)系肛捍,從而為Java層訪問JNI層提供了通道。
2.1.3 總結(jié):
總結(jié)之众,int_register_android_os_Binder方法的主要功能:
- 通過gBinderOffsets拙毫,保存Java層Binder類的信息,為JNI層訪問Java層提供了通道
- 通過RegisterMethodsOrDie棺禾,將gBinderMethods數(shù)組完成映射關(guān)系缀蹄,從而為Java層訪問JNI層提供通道
也就是說該過程建立了Binder在Native層與framework之間的相互調(diào)用的橋梁。
2.2 int_register_android_os_BinderInternal()函數(shù)
注冊(cè) BinderInternal
// frameworks/base/core/jni/android_util_Binder.cpp 935行
static int int_register_android_os_BinderInternal(JNIEnv* env)
{
//其中kBinderInternalPathName
jclass clazz = FindClassOrDie(env, kBinderInternalPathName);
gBinderInternalOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
gBinderInternalOffsets.mForceGc = GetStaticMethodIDOrDie(env, clazz, "forceBinderGc", "()V");
return RegisterMethodsOrDie(
env, kBinderInternalPathName,
gBinderInternalMethods, NELEM(gBinderInternalMethods));
}
注冊(cè) Binderinternal類的jni方法,gBinderInternaloffsets保存了BinderInternal的forceBinderGc()方法缺前。
下面是BinderInternal類的JNI方法注冊(cè)
// frameworks/base/core/jni/android_util_Binder.cpp 925號(hào)
static const JNINativeMethod gBinderInternalMethods[] = {
{ "getContextObject", "()Landroid/os/IBinder;", (void*)android_os_BinderInternal_getContextObject },
{ "joinThreadPool", "()V", (void*)android_os_BinderInternal_joinThreadPool },
{ "disableBackgroundScheduling", "(Z)V", (void*)android_os_BinderInternal_disableBackgroundScheduling },
{ "handleGc", "()V", (void*)android_os_BinderInternal_handleGc }
};
該過程 和注冊(cè)Binder類 JNI非常類似蛀醉,也就是說該過程建立了是BinderInternal類在Native層與framework層之間的相互調(diào)用的橋梁。
2.3 int_register_android_os_BinderProxy()函數(shù)
// frameworks/base/core/jni/android_util_Binder.cpp 1254行
static int int_register_android_os_BinderProxy(JNIEnv* env)
{
//gErrorOffsets 保存了Error類信息
jclass clazz = FindClassOrDie(env, "java/lang/Error");
gErrorOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
//gBinderProxyOffsets保存了BinderProxy類的信息
//其中kBinderProxyPathName="android/os/BinderProxy"
clazz = FindClassOrDie(env, kBinderProxyPathName);
gBinderProxyOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
gBinderProxyOffsets.mConstructor = GetMethodIDOrDie(env, clazz, "<init>", "()V");
gBinderProxyOffsets.mSendDeathNotice = GetStaticMethodIDOrDie(env, clazz, "sendDeathNotice", "(Landroid/os/IBinder$DeathRecipient;)V");
gBinderProxyOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");
gBinderProxyOffsets.mSelf = GetFieldIDOrDie(env, clazz, "mSelf", "Ljava/lang/ref/WeakReference;");
gBinderProxyOffsets.mOrgue = GetFieldIDOrDie(env, clazz, "mOrgue", "J");
//gClassOffsets保存了Class.getName()方法
clazz = FindClassOrDie(env, "java/lang/Class");
gClassOffsets.mGetName = GetMethodIDOrDie(env, clazz, "getName", "()Ljava/lang/String;");
return RegisterMethodsOrDie(
env, kBinderProxyPathName,
gBinderProxyMethods, NELEM(gBinderProxyMethods));
}
注冊(cè)BinderPoxy類的JNI方法衅码,gBinderProxyOffsets保存了BinderProxy的構(gòu)造方法拯刁,sendDeathNotice(),mObject逝段,mSelf垛玻,mOrgue信息。
我們來看下gBinderProxyOffsets
2.3.1 gBinderProxyOffsets結(jié)構(gòu)體
// frameworks/base/core/jni/android_util_Binder.cpp 95行
static struct binderproxy_offsets_t {
// Class state.
// 對(duì)應(yīng)的是 class對(duì)象 android.os.BinderProxy
jclass mClass;
// 對(duì)應(yīng)的是 BinderProxy的構(gòu)造函數(shù)
jmethodID mConstructor;
// 對(duì)應(yīng)的是 BinderProxy的sendDeathNotice方法
jmethodID mSendDeathNotice;
// Object state.
// 對(duì)應(yīng)的是 BinderProxy的 mObject字段
jfieldID mObject;
// 對(duì)應(yīng)的是 BinderProxy的mSelf字段
jfieldID mSelf;
// 對(duì)應(yīng)的是 BinderProxymOrgue字段
jfieldID mOrgue;
} gBinderProxyOffsets;
PS: 這里補(bǔ)充下BinderProxy類是Binder類的內(nèi)部類
下面BinderProxy類的JNI方法注冊(cè):
// frameworks/base/core/jni/android_util_Binder.cpp 1241行
static const JNINativeMethod gBinderProxyMethods[] = {
/* 名稱, 簽名, 函數(shù)指針 */
{"pingBinder", "()Z", (void*)android_os_BinderProxy_pingBinder},
{"isBinderAlive", "()Z", (void*)android_os_BinderProxy_isBinderAlive},
{"getInterfaceDescriptor", "()Ljava/lang/String;", (void*)android_os_BinderProxy_getInterfaceDescriptor},
{"transactNative", "(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z", (void*)android_os_BinderProxy_transact},
{"linkToDeath", "(Landroid/os/IBinder$DeathRecipient;I)V", (void*)android_os_BinderProxy_linkToDeath},
{"unlinkToDeath", "(Landroid/os/IBinder$DeathRecipient;I)Z", (void*)android_os_BinderProxy_unlinkToDeath},
{"destroy", "()V", (void*)android_os_BinderProxy_destroy},
};
該過程上面非常類似奶躯,也就是說該過程建立了是BinderProxy類在Native層與framework層之間的相互調(diào)用的橋梁帚桩。
三、注冊(cè)服務(wù)
注冊(cè)服務(wù)在ServiceManager里面
//frameworks/base/core/java/android/os/ServiceManager.java 70行
public static void addService(String name, IBinder service, boolean allowIsolated) {
try {
//getIServiceManager()是獲取ServiceManagerProxy對(duì)象
// addService() 是執(zhí)行注冊(cè)服務(wù)操作
getIServiceManager().addService(name, service, allowIsolated);
} catch (RemoteException e) {
Log.e(TAG, "error in addService", e);
}
}
(一) 嘹黔、先來看下getIServiceManager()方法
//frameworks/base/core/java/android/os/ServiceManager.java 70行
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
// Find the service manager
sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
return sServiceManager;
}
通過上面账嚎,大家的第一反應(yīng)應(yīng)該是sServiceManager是單例的。第二反映是如果想知道sServiceManager的值儡蔓,必須了解BinderInternal.getContextObject()的返回值和 ServiceManagerNative.asInterface()方法的內(nèi)部執(zhí)行郭蕉,那我們就來詳細(xì)了解下
1、先來看下BinderInternal.getContextObject()方法
//frameworks/base/core/java/com/android/internal/os/BinderInternal.java 88行
/**
* Return the global "context object" of the system. This is usually
* an implementation of IServiceManager, which you can use to find
* other services.
*/
public static final native IBinder getContextObject();
可見BinderInternal.getContextObject()最終會(huì)調(diào)用JNI通過C層來實(shí)現(xiàn)浙值,那我們就繼續(xù)跟蹤
1.1恳不、android_os_BinderInternal_getContextObject)函數(shù)
// frameworks/base/core/jni/android_util_Binder.cpp 899行
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
return javaObjectForIBinder(env, b);
}
看到上面的代碼 大家有沒有熟悉的感覺,前面講過了:對(duì)于ProcessState::self() -> getContextObject()
對(duì)于ProcessState::self()->getContextObject()可以理解為new BpBinder(0)开呐,那就剩下 javaObjectForIBinder(env, b) 那我們就來看下這個(gè)函數(shù)
1.2烟勋、javaObjectForIBinder()函數(shù)
// frameworks/base/core/jni/android_util_Binder.cpp 547行
jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
{
if (val == NULL) return NULL;
//返回false
if (val->checkSubclass(&gBinderOffsets)) {
jobject object = static_cast<JavaBBinder*>(val.get())->object();
return object;
}
AutoMutex _l(mProxyLock);
jobject object = (jobject)val->findObject(&gBinderProxyOffsets);
//第一次 object為null
if (object != NULL) {
//查找是否已經(jīng)存在需要使用的BinderProxy對(duì)應(yīng),如果有筐付,則返回引用卵惦。
jobject res = jniGetReferent(env, object);
if (res != NULL) {
return res;
}
android_atomic_dec(&gNumProxyRefs);
val->detachObject(&gBinderProxyOffsets);
env->DeleteGlobalRef(object);
}
//創(chuàng)建BinderProxy對(duì)象
object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
if (object != NULL) {
// BinderProxy.mObject成員變量記錄BpBinder對(duì)象
env->SetLongField(object, gBinderProxyOffsets.mObject, (jlong)val.get());
val->incStrong((void*)javaObjectForIBinder);
jobject refObject = env->NewGlobalRef(
env->GetObjectField(object, gBinderProxyOffsets.mSelf));
//將BinderProxy對(duì)象信息附加到BpBinder的成員變量mObjects中
val->attachObject(&gBinderProxyOffsets, refObject,
jnienv_to_javavm(env), proxy_cleanup);
sp<DeathRecipientList> drl = new DeathRecipientList;
drl->incStrong((void*)javaObjectForIBinder);
// BinderProxy.mOrgue成員變量記錄死亡通知對(duì)象
env->SetLongField(object, gBinderProxyOffsets.mOrgue, reinterpret_cast<jlong>(drl.get()));
android_atomic_inc(&gNumProxyRefs);
incRefsCreated(env);
}
return object;
}
上面的大致流程如下:
- 1、第二個(gè)入?yún)al在有些時(shí)候指向BpBinder瓦戚,有些時(shí)候指向JavaBBinder
- 2沮尿、至于是BpBinder還是JavaBBinder是通過if (val->checkSubclass(&gBinderOffsets)) 這個(gè)函數(shù)來區(qū)分的,如果是JavaBBinder较解,則為true畜疾,則就會(huì)通過成員函數(shù)object(),返回一個(gè)Java對(duì)象印衔,這個(gè)對(duì)象就是Java層的Binder對(duì)象啡捶。由于我們這里是BpBinder,所以是 ** 返回false**
- 3如果是BpBinder奸焙,會(huì)先判斷是不是第一次瞎暑,如果是第一次,下面的object為null彤敛。
jobject object = (jobject)val->findObject(&gBinderProxyOffsets);
如果不是第一次,就會(huì)先查找是否已經(jīng)存在需要使用的BinderProxy對(duì)象了赌,如果找到就會(huì)返回引用
- 4墨榄、如果沒有找到可用的引用,就new一個(gè)BinderProxy對(duì)象
所以主要是根據(jù)BpBinder(C++) 生成BinderProxy(Java對(duì)象)勿她,主要工作是創(chuàng)建BinderProxy對(duì)象袄秩,并把BpBinder對(duì)象地址保存到BinderProxy.mObject成員變量。到此逢并,可知ServiceManagerNative.asInterface(BinderInternal.getContextObject()) 等價(jià)于
ServiceManagerNative.asInterface(new BinderProxy())
2播揪、再來看下ServiceManagerNative.asInterface()方法
//frameworks/base/core/java/android/os/ServiceManagerNative.java 33行
/**
* Cast a Binder object into a service manager interface, generating
* a proxy if needed.
* 將Binder對(duì)象轉(zhuǎn)換service manager interface,如果需要筒狠,生成一個(gè)代理。
*/
static public IServiceManager asInterface(IBinder obj)
{
//obj為 BpBinder
// 如果 obj為null 則直接返回
if (obj == null) {
return null;
}
// 由于是BpBinder箱沦,所以BpBinder的queryLocalInterface(descriptor) 默認(rèn)返回null
IServiceManager in =
(IServiceManager)obj.queryLocalInterface(descriptor);
if (in != null) {
return in;
}
return new ServiceManagerProxy(obj);
}
我們看下這個(gè)obj.queryLocalInterface(descriptor)方法辩恼,其實(shí)他是調(diào)用的IBinder的native方法如下
public interface IBinder {
.....
/**
* Attempt to retrieve a local implementation of an interface
* for this Binder object. If null is returned, you will need
* to instantiate a proxy class to marshall calls through
* the transact() method.
*/
public IInterface queryLocalInterface(String descriptor);
.....
}
通過注釋我們知道,queryLocalInterface是查詢本地的對(duì)象,我簡單解釋下什么是本地對(duì)象谓形,這里的本地對(duì)象是指灶伊,如果進(jìn)行IPC調(diào)用,如果是兩個(gè)進(jìn)程是同一個(gè)進(jìn)程寒跳,即對(duì)象是本地對(duì)象聘萨;如果兩個(gè)進(jìn)程是兩個(gè)不同的進(jìn)程,則返回的遠(yuǎn)端的代理類童太。所以在BBinder的子類BnInterface中米辐,重載了這個(gè)方法,返回this书释,而在BpInterface并沒有重載這個(gè)方法翘贮。又因?yàn)閝ueryLocalInterface 默認(rèn)返回的是null,所以obj.queryLocalInterface=null爆惧。
所以最后結(jié)論是 return new ServiceManagerProxy(obj);
那我們來看下ServiceManagerProxy
2.1狸页、ServiceManagerProxy
PS:ServiceManagerProxy是ServiceManagerNative類的內(nèi)部類
//frameworks/base/core/java/android/os/ServiceManagerNative.java 109行
class ServiceManagerProxy implements IServiceManager {
public ServiceManagerProxy(IBinder remote) {
mRemote = remote;
}
}
mRemote為BinderProxy對(duì)象,該BinderProxy對(duì)象對(duì)應(yīng)于BpBinder(0)扯再,其作為binder代理端芍耘,指向native的層的Service Manager。
所以說:
ServiceManager.getIServiceManager最終等價(jià)于new ServiceManagerProxy(new BinderProxy())熄阻。所以
getIServiceManager().addService()
等價(jià)于
ServiceManagerNative.addService();
framework層的ServiceManager的調(diào)用實(shí)際的工作確實(shí)交給了ServiceManagerProxy的成員變量BinderProxy斋竞;而BinderProxy通過JNI的方式,最終會(huì)調(diào)用BpBinder對(duì)象饺律;可見上層binder結(jié)構(gòu)的核心功能依賴native架構(gòu)的服務(wù)來完成的窃页。
(二) addService()方法詳解
上面已經(jīng)知道了
getIServiceManager().addService(name, service, allowIsolated);
等價(jià)于
ServiceManagerProxy..addService(name, service, allowIsolated);
PS:上面的ServiceManagerProxy代表ServiceManagerProxy對(duì)象
所以讓我們來看下ServiceManagerProxy的addService()方法
1跺株、ServiceManagerProxy的addService()
//frameworks/base/core/java/android/os/ServiceManagerNative.java 142行
public void addService(String name, IBinder service, boolean allowIsolated)
throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
//是個(gè)常量是 “android.os.IServiceManager"
data.writeInterfaceToken(IServiceManager.descriptor);
data.writeString(name);
data.writeStrongBinder(service);
data.writeInt(allowIsolated ? 1 : 0);
mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
reply.recycle();
data.recycle();
}
里面代碼都比較容易理解,這里重點(diǎn)說下data.writeStrongBinder(service); 和 mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
2脖卖、Parcel.writeStrongBinder()
那我們就來看下Parcel的writeStrongBinder()方法
//frameworks/base/core/java/android/os/Parcel.java 583行
/**
* Write an object into the parcel at the current dataPosition(),
* growing dataCapacity() if needed.
*/
public final void writeStrongBinder(IBinder val) {
nativeWriteStrongBinder(mNativePtr, val);
}
先看下注釋乒省,翻譯一下
在當(dāng)前的dataPosition()的位置上寫入一個(gè)對(duì)象,如果空間不足畦木,則增加空間
通過上面代碼我們知道 writeStrongBinder() 方法里面實(shí)際是調(diào)用的 nativeWriteStrongBinder() 方法袖扛,那我們來看下 ** nativeWriteStrongBinder()** 方法
2.1 nativeWriteStrongBinder()方法
/frameworks/base/core/java/android/os/Parcel.java 265行
private static native void nativeWriteStrongBinder(long nativePtr, IBinder val);
我們知道了nativeWriteStrongBinder是一個(gè)native方法,那我們繼續(xù)跟蹤
2.2 android_os_Parcel_writeStrongBinder()函數(shù)
//frameworks/base/core/jni/android_os_Parcel.cpp 298行
static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr, jobject object)
{
//將java層Parcel轉(zhuǎn)換為native層Parcel
Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
if (parcel != NULL) {
const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));
if (err != NO_ERROR) {
signalExceptionForError(env, clazz, err);
}
}
}
這里主要涉及的兩個(gè)重要的函數(shù)
- writeStrongBinder()函數(shù)
- ibinderForJavaObject()函數(shù)
那我們就來詳細(xì)研究這兩個(gè)函數(shù)
2.2.1 ibinderForJavaObject()函數(shù)
// frameworks/base/core/jni/android_util_Binder.cpp 603行
sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj)
{
if (obj == NULL) return NULL;
//Java層的Binder對(duì)象
//mClass指向Java層中的Binder class
if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {
JavaBBinderHolder* jbh = (JavaBBinderHolder*)
env->GetLongField(obj, gBinderOffsets.mObject);
//get()返回一個(gè)JavaBBinder十籍,繼承自BBinder
return jbh != NULL ? jbh->get(env, obj) : NULL;
}
//Java層的BinderProxy對(duì)象
// mClass 指向Java層的BinderProxy class
if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {
//返回一個(gè) BpBinder蛆封,mObject 是它的地址值
return (IBinder*)env->GetLongField(obj, gBinderProxyOffsets.mObject);
}
return NULL;
}
根據(jù)Binder(Java)生成JavaBBinderHolder(C++)對(duì)象,主要工作是創(chuàng)建JavaBBinderHolder對(duì)象勾栗,并把JavaBBinder對(duì)象保存在到Binder.mObject成員變量惨篱。
- 這個(gè)函數(shù),本質(zhì)就是根據(jù)傳進(jìn)來的Java對(duì)象找到對(duì)應(yīng)的C++對(duì)象围俘,這里的obj可能會(huì)指向兩種對(duì)象:Binder對(duì)象和BinderProxy對(duì)象砸讳。
- 如果傳進(jìn)來的是Binder對(duì)象,則會(huì)把gBinderOffsets.mObject轉(zhuǎn)化為JavaBBinderHolder界牡,并從中獲得一個(gè)JavaBBinder對(duì)象(JavaBBinder繼承自BBinder)簿寂。
- 如果是BinderProxy對(duì)象,會(huì)返回一個(gè)BpBinder宿亡,這個(gè)BpBinder的地址值保存在gBinderProxyOffsets.mObject中
在上面的代碼里面調(diào)用了get()函數(shù)常遂,如下圖
JavaBBinderHolder* jbh = (JavaBBinderHolder*)
env->GetLongField(obj, gBinderOffsets.mObject);
//get()返回一個(gè)JavaBBinder,繼承自BBinder
return jbh != NULL ? jbh->get(env, obj) : NULL;
那我們就來研究下JavaBBinderHolder.get()函數(shù)
2.2.1.1 JavaBBinderHolder.get()函數(shù)
// frameworks/base/core/jni/android_util_Binder.cpp 316行
sp<JavaBBinder> get(JNIEnv* env, jobject obj)
{
AutoMutex _l(mLock);
sp<JavaBBinder> b = mBinder.promote();
if (b == NULL) {
//首次進(jìn)來挽荠,創(chuàng)建JavaBBinder對(duì)象
b = new JavaBBinder(env, obj);
mBinder = b;
}
return b;
}
JavaBBinderHolder有一個(gè)成員變量mBinder克胳,保存當(dāng)前創(chuàng)建的JavaBBinder對(duì)象,這是一個(gè)wp類型的圈匆,可能會(huì)被垃圾回收器給回收的毯欣,所以每次使用前都需要先判斷是否存在。
那我們?cè)賮砜纯聪翵avaBBinder的初始化
2.2.1.2 JavaBBinder的初始化
JavaBBinder(JNIEnv* env, jobject object)
: mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object))
{
ALOGV("Creating JavaBBinder %p\n", this);
android_atomic_inc(&gNumLocalRefs);
incRefsCreated(env);
}
創(chuàng)建JavaBBinder臭脓,該對(duì)象繼承于BBinder對(duì)象酗钞。
2.2.1.3 總結(jié)
所以說 data.writeStrongBinder(Service)最終等價(jià)于parcel->writeStringBinder(new JavaBBinder(env, obj));
2.2.2、writeStrongBinder() 函數(shù)
// frameworks/native/libs/binder/Parcel.cpp 872行
status_t Parcel::writeStrongBinder(const sp<IBinder>& val)
{
return flatten_binder(ProcessState::self(), val, this);
}
我們看到writeStrongBinder()函數(shù) 實(shí)際上是調(diào)用的flatten_binder()函數(shù)
2.2.2.1来累、 writeStrongBinder() 函數(shù)
//frameworks/native/libs/binder/Parcel.cpp 205行
status_t flatten_binder(const sp<ProcessState>& /*proc*/,
const sp<IBinder>& binder, Parcel* out)
{
flat_binder_object obj;
obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
if (binder != NULL) {
IBinder *local = binder->localBinder();
if (!local) {
//如果不是本地Binder
BpBinder *proxy = binder->remoteBinder();
const int32_t handle = proxy ? proxy->handle() : 0;
//遠(yuǎn)程Binder
obj.type = BINDER_TYPE_HANDLE;
obj.binder = 0;
obj.handle = handle;
obj.cookie = 0;
} else {
//如果是本地Binder
obj.type = BINDER_TYPE_BINDER;
obj.binder = reinterpret_cast<uintptr_t>(local->getWeakRefs());
obj.cookie = reinterpret_cast<uintptr_t>(local);
}
} else {
//本地Binder
obj.type = BINDER_TYPE_BINDER;
obj.binder = 0;
obj.cookie = 0;
}
return finish_flatten_binder(binder, obj, out);
}
將Binder對(duì)象扁平化思喊,轉(zhuǎn)換成flat_binder_object對(duì)象
- 對(duì)于Binder實(shí)體蛤袒,則cookie記錄Binder實(shí)體指針
- 對(duì)于Binder代理萍程,則用handle記錄Binder代理的句柄
關(guān)于localBinder阀湿,在Binder.cpp里面
BBinder* BBinder::localBinder()
{
return this;
}
BBinder* IBinder::localBinder()
{
return NULL;
}
在最后面調(diào)用了finish_flatten_binder()函數(shù),那我們?cè)傺芯肯耭inish_flatten_binder()函數(shù)
2.2.2.2领猾、 finish_flatten_binder() 函數(shù)
//frameworks/native/libs/binder/Parcel.cpp 199行
inline static status_t finish_flatten_binder(
const sp<IBinder>& , const flat_binder_object& flat, Parcel* out)
{
return out->writeObject(flat, false);
}
這個(gè)大家看明白了吧米同,就是寫入一個(gè)object骇扇。
Parcel.writeStrongBinder()整個(gè)流程已經(jīng)結(jié)束了。下面讓我回來看下
ServiceManagerProxy的addService()中的mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
3面粮、IBinder.transact()
ServiceManagerProxy的addService()中的mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);里面的mRemote的類型是BinderProxy的少孝,所以調(diào)用是BinderProxy的transact()方法,那我們就進(jìn)去看看
3.1熬苍、BinderProxy.transact()
溫馨提示:BinderProxy類是Binder類的內(nèi)部類
他其實(shí)是重寫的IBinder的里面的transact()方法稍走,那讓我們看下IBinder里面
// frameworks/base/core/java/android/os/IBinder.java 223行
/**
* Perform a generic operation with the object.
*
* @param code The action to perform. This should
* be a number between {@link #FIRST_CALL_TRANSACTION} and
* {@link #LAST_CALL_TRANSACTION}.
* @param data Marshalled data to send to the target. Must not be null.
* If you are not sending any data, you must create an empty Parcel
* that is given here.
* @param reply Marshalled data to be received from the target. May be
* null if you are not interested in the return value.
* @param flags Additional operation flags. Either 0 for a normal
* RPC, or {@link #FLAG_ONEWAY} for a one-way RPC.
*/
public boolean transact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException;
其實(shí)讓大家看這個(gè)主要是向大家說下這個(gè)注釋,(__) 嘻嘻……
翻譯一下
- 用對(duì)象執(zhí)行一個(gè)操作
- 參數(shù)code 為操作碼柴底,是介于FIRST_CALL_TRANSACTION和LAST_CALL_TRANSACTION之間
- 參數(shù)data 是要發(fā)往目標(biāo)的數(shù)據(jù)婿脸,一定不能null,如果你沒有數(shù)據(jù)要發(fā)送柄驻,你也要?jiǎng)?chuàng)建一個(gè)Parcel狐树,哪怕是空的。
- 參數(shù)reply 是從目標(biāo)發(fā)過來的數(shù)據(jù)鸿脓,如果你對(duì)這個(gè)數(shù)據(jù)沒興趣褪迟,這個(gè)數(shù)據(jù)是可以為null的。
- 參數(shù)flags 一個(gè)操作標(biāo)志位答憔,要么是0代表普通的RPC,要么是FLAG_ONEWAY代表單一方向的RPC即不管返回值
這時(shí)候我們?cè)倩貋砜?/p>
/frameworks/base/core/java/android/os/Binder.java 501行
final class BinderProxy implements IBinder {
public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
Binder.checkParcel(this, code, data, "Unreasonably large binder buffer");
if (Binder.isTracingEnabled()) { Binder.getTransactionTracker().addTrace(); }
return transactNative(code, data, reply, flags);
}
}
先來看下 Binder.checkParcel方法
3.1.1掀抹、Binder.checkParcel()
/frameworks/base/core/java/android/os/Binder.java 415行
static void checkParcel(IBinder obj, int code, Parcel parcel, String msg) {
if (CHECK_PARCEL_SIZE && parcel.dataSize() >= 800*1024) {
// Trying to send > 800k, this is way too much
StringBuilder sb = new StringBuilder();
sb.append(msg);
sb.append(": on ");
sb.append(obj);
sb.append(" calling ");
sb.append(code);
sb.append(" size ");
sb.append(parcel.dataSize());
sb.append(" (data: ");
parcel.setDataPosition(0);
sb.append(parcel.readInt());
sb.append(", ");
sb.append(parcel.readInt());
sb.append(", ");
sb.append(parcel.readInt());
sb.append(")");
Slog.wtfStack(TAG, sb.toString());
}
}
這段代碼很簡單虐拓,主要是檢查Parcel大小是否大于800K。
執(zhí)行完Binder.checkParcel后傲武,直接調(diào)用了transactNative()方法蓉驹,那我們就來看看transactNative()方法
3.1.2、transactNative()方法
// frameworks/base/core/java/android/os/Binder.java 507行
public native boolean transactNative(int code, Parcel data, Parcel reply,
int flags) throws RemoteException;
我們看到他是一個(gè)native函數(shù)揪利,后面肯定經(jīng)過JNI調(diào)用到了native層态兴,根據(jù)包名,它對(duì)應(yīng)的方法應(yīng)該是"android_os_BinderProxy_transact"函數(shù)疟位,那我們繼續(xù)跟蹤
3.1.3瞻润、android_os_BinderProxy_transact()函數(shù)
// frameworks/base/core/jni/android_util_Binder.cpp 1083行
static jboolean android_os_BinderProxy_transact(JNIEnv*env, jobject obj,
jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException
{
if (dataObj == NULL) {
jniThrowNullPointerException(env, NULL);
return JNI_FALSE;
}
// 將 java Parcel轉(zhuǎn)化為native Parcel
Parcel * data = parcelForJavaObject(env, dataObj);
if (data == NULL) {
return JNI_FALSE;
}
Parcel * reply = parcelForJavaObject(env, replyObj);
if (reply == NULL && replyObj != NULL) {
return JNI_FALSE;
}
// gBinderProxyOffsets.mObject中保存的是new BpBinder(0)對(duì)象
IBinder * target = (IBinder *)
env -> GetLongField(obj, gBinderProxyOffsets.mObject);
if (target == NULL) {
jniThrowException(env, "java/lang/IllegalStateException", "Binder has been finalized!");
return JNI_FALSE;
}
ALOGV("Java code calling transact on %p in Java object %p with code %"PRId32"\n",
target, obj, code);
bool time_binder_calls;
int64_t start_millis;
if (kEnableBinderSample) {
// Only log the binder call duration for things on the Java-level main thread.
// But if we don't
time_binder_calls = should_time_binder_calls();
if (time_binder_calls) {
start_millis = uptimeMillis();
}
}
//printf("Transact from Java code to %p sending: ", target); data->print();
// 此處便是BpBinder:: transact(),經(jīng)過native層甜刻,進(jìn)入Binder驅(qū)動(dòng)绍撞。
status_t err = target -> transact(code, * data, reply, flags);
//if (reply) printf("Transact from Java code to %p received: ", target); reply->print();
if (kEnableBinderSample) {
if (time_binder_calls) {
conditionally_log_binder_call(start_millis, target, code);
}
}
if (err == NO_ERROR) {
return JNI_TRUE;
} else if (err == UNKNOWN_TRANSACTION) {
return JNI_FALSE;
}
signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/, data -> dataSize());
return JNI_FALSE;
}
通過上面的代碼我們知道,Java層BinderProxy.transact()最終交由Native層的BpBinder::transact()完成得院。這部分之前代碼講解過了傻铣,我這里就不詳細(xì)說明了。不過注意祥绞,該方法可能會(huì)拋出RemoteException非洲。
(二)鸭限、總結(jié)
所以 整個(gè) addService的核心可以縮寫為向下面的代碼
public void addService(String name, IBinder service, boolean allowIsolated)
throws RemoteException {
...
//此處還需要將Java層的Parcel轉(zhuǎn)化為Native層的Parcel
Parcel data = Parcel.obtain();
data->writeStrongBinder(new JavaBBinder(env, obj));
//與Binder驅(qū)動(dòng)交互
BpBinder::transact(ADD_SERVICE_TRANSACTION, *data, reply, 0);
...
}
說白了,注冊(cè)服務(wù)過程就是通過BpBinder來發(fā)送ADD_SERVICE_TRANSACTION命令两踏,與binder驅(qū)動(dòng)進(jìn)行數(shù)據(jù)交互败京。
四、獲取服務(wù)
(一)缆瓣、ServiceManager.getService()方法
//frameworks/base/core/java/android/os/ServiceManager.java 49行
public static IBinder getService(String name) {
try {
//先從緩存中查看
IBinder service = sCache.get(name);
if (service != null) {
return service;
} else {
return getIServiceManager().getService(name);
}
} catch (RemoteException e) {
Log.e(TAG, "error in getService", e);
}
return null;
}
- 1喧枷、先從緩存中取出,如果有弓坞,則直接return隧甚。其中sCache是以HashMap格式的緩存
- 2、如果沒有調(diào)用getIServiceManager().getService(name)獲取一個(gè)渡冻,并且return
通過前面的內(nèi)容我們知道
getIServiceManager()
等價(jià)于
new ServiceManagerProxy(new BinderProxy())
那我們來下ServiceManagerProxy的getService()方法
1戚扳、ServiceManagerProxy.getService(name)
// frameworks/base/core/java/android/os/ServiceManagerNative.java 118行
public IBinder getService(String name) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IServiceManager.descriptor);
data.writeString(name);
//mRemote為BinderProxy
mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);
//從replay里面解析出獲取的IBinder對(duì)象
IBinder binder = reply.readStrongBinder();
reply.recycle();
data.recycle();
return binder;
}
這里面有兩個(gè)重點(diǎn)方法,一個(gè)是 mRemote.transact(),一個(gè)是 reply.readStrongBinder()族吻。那我們就逐步研究下
2帽借、mRemote.transact()方法
我們mRemote其實(shí)是BinderPoxy,那我們來看下BinderProxy的transact方法
//frameworks/base/core/java/android/os/Binder.java 501行
public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
Binder.checkParcel(this, code, data, "Unreasonably large binder buffer");
if (Binder.isTracingEnabled()) { Binder.getTransactionTracker().addTrace(); }
return transactNative(code, data, reply, flags);
}
// frameworks/base/core/java/android/os/Binder.java 507行
public native boolean transactNative(int code, Parcel data, Parcel reply,
int flags) throws RemoteException;
關(guān)于Binder.checkParcel()方法超歌,上面已經(jīng)說過了砍艾,就不詳細(xì)說了。transact()方法其實(shí)是調(diào)用了natvie的transactNative()方法巍举,這樣就進(jìn)入了JNI里面了
2.1脆荷、mRemote.transact()方法
// frameworks/base/core/jni/android_util_Binder.cpp 1083行
static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException
{
if (dataObj == NULL) {
jniThrowNullPointerException(env, NULL);
return JNI_FALSE;
}
//Java的 Parcel 轉(zhuǎn)為native的 Parcel
Parcel* data = parcelForJavaObject(env, dataObj);
if (data == NULL) {
return JNI_FALSE;
}
Parcel* reply = parcelForJavaObject(env, replyObj);
if (reply == NULL && replyObj != NULL) {
return JNI_FALSE;
}
// gBinderProxyOffsets.mObject中保存的的是new BpBinder(0)對(duì)象
IBinder* target = (IBinder*)
env->GetLongField(obj, gBinderProxyOffsets.mObject);
if (target == NULL) {
jniThrowException(env, "java/lang/IllegalStateException", "Binder has been finalized!");
return JNI_FALSE;
}
ALOGV("Java code calling transact on %p in Java object %p with code %" PRId32 "\n",
target, obj, code);
bool time_binder_calls;
int64_t start_millis;
if (kEnableBinderSample) {
// Only log the binder call duration for things on the Java-level main thread.
// But if we don't
time_binder_calls = should_time_binder_calls();
if (time_binder_calls) {
start_millis = uptimeMillis();
}
}
//printf("Transact from Java code to %p sending: ", target); data->print();
//gBinderProxyOffseets.mObject中保存的是new BpBinder(0) 對(duì)象
status_t err = target->transact(code, *data, reply, flags);
//if (reply) printf("Transact from Java code to %p received: ", target); reply->print();
if (kEnableBinderSample) {
if (time_binder_calls) {
conditionally_log_binder_call(start_millis, target, code);
}
}
if (err == NO_ERROR) {
return JNI_TRUE;
} else if (err == UNKNOWN_TRANSACTION) {
return JNI_FALSE;
}
signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/, data->dataSize());
return JNI_FALSE;
}
上面代碼中,有一段重點(diǎn)代碼
status_t err = target->transact(code, *data, reply, flags);
現(xiàn)在 我們看一下他里面的事情
2.2懊悯、BpBinder::transact()函數(shù)
/frameworks/native/libs/binder/BpBinder.cpp 159行
status_t BpBinder::transact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
if (mAlive) {
status_t status = IPCThreadState::self()->transact(
mHandle, code, data, reply, flags);
if (status == DEAD_OBJECT) mAlive = 0;
return status;
}
return DEAD_OBJECT;
}
其實(shí)是調(diào)用的IPCThreadState的transact()函數(shù)
2.3蜓谋、BpBinder::transact()函數(shù)
//frameworks/native/libs/binder/IPCThreadState.cpp 548行
status_t IPCThreadState::transact(int32_t handle,
uint32_t code, const Parcel& data,
Parcel* reply, uint32_t flags)
{
status_t err = data.errorCheck(); //數(shù)據(jù)錯(cuò)誤檢查
flags |= TF_ACCEPT_FDS;
....
if (err == NO_ERROR) {
// 傳輸數(shù)據(jù)
err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);
}
...
// 默認(rèn)情況下,都是采用非oneway的方式, 也就是需要等待服務(wù)端的返回結(jié)果
if ((flags & TF_ONE_WAY) == 0) {
if (reply) {
//等待回應(yīng)事件
err = waitForResponse(reply);
}else {
Parcel fakeReply;
err = waitForResponse(&fakeReply);
}
} else {
err = waitForResponse(NULL, NULL);
}
return err;
}
主要就是兩個(gè)步驟
- 首先,調(diào)用writeTransactionData()函數(shù) 傳輸數(shù)據(jù)
- 其次炭分,調(diào)用waitForResponse()函數(shù)來獲取返回結(jié)果
那我們來看下waitForResponse()函數(shù)里面的重點(diǎn)實(shí)現(xiàn)
2.4桃焕、IPCThreadState::waitForResponse函數(shù)
//frameworks/native/libs/binder/IPCThreadState.cpp 712行
status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
{
int32_t cmd;
int32_t err;
while (1) {
if ((err=talkWithDriver()) < NO_ERROR) break;
...
cmd = mIn.readInt32();
switch (cmd) {
case BR_REPLY:
{
binder_transaction_data tr;
err = mIn.read(&tr, sizeof(tr));
if (reply) {
if ((tr.flags & TF_STATUS_CODE) == 0) {
//當(dāng)reply對(duì)象回收時(shí),則會(huì)調(diào)用freeBuffer來回收內(nèi)存
reply->ipcSetDataReference(
reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
tr.data_size,
reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
tr.offsets_size/sizeof(binder_size_t),
freeBuffer, this);
} else {
...
}
}
}
case :...
}
}
...
return err;
}
這時(shí)候就在等待回復(fù)了捧毛,如果有回復(fù)观堂,則通過cmd = mIn.readInt32()函數(shù)獲取命令
2.5、IPCThreadState::waitForResponse函數(shù)
//
void binder_send_reply(struct binder_state *bs,
struct binder_io *reply,
binder_uintptr_t buffer_to_free,
int status)
{
struct {
uint32_t cmd_free;
binder_uintptr_t buffer;
uint32_t cmd_reply;
struct binder_transaction_data txn;
} __attribute__((packed)) data;
//free buffer命令
data.cmd_free = BC_FREE_BUFFER;
data.buffer = buffer_to_free;
// reply命令
data.cmd_reply = BC_REPLY; // reply命令
data.txn.target.ptr = 0;
data.txn.cookie = 0;
data.txn.code = 0;
if (status) {
...
} else {=
data.txn.flags = 0;
data.txn.data_size = reply->data - reply->data0;
data.txn.offsets_size = ((char*) reply->offs) - ((char*) reply->offs0);
data.txn.data.ptr.buffer = (uintptr_t)reply->data0;
data.txn.data.ptr.offsets = (uintptr_t)reply->offs0;
}
//向Binder驅(qū)動(dòng)通信
binder_write(bs, &data, sizeof(data));
}
binder_write將BC_FREE_BUFFER和BC_REPLY命令協(xié)議發(fā)送給驅(qū)動(dòng)呀忧,進(jìn)入驅(qū)動(dòng)型将。
在驅(qū)動(dòng)里面bingder_ioctl -> binder_ioctl_write_read ->binder_thread_write,由于是BC_REPLY命令協(xié)議荐虐,則進(jìn)入binder_transaction七兜,該方法會(huì)向請(qǐng)求服務(wù)的線程TODO隊(duì)列插入事務(wù)。接來下福扬,請(qǐng)求服務(wù)的進(jìn)程在執(zhí)行talkWithDriver的過程執(zhí)行到binder_thread_read()腕铸,處理TODO隊(duì)列的事物惜犀。
3、Parcel.readStrongBinder()方法
其實(shí)Parcel.readStrongBinder()的過程基本上就是writeStrongBinder的過程狠裹。
我們先來看下它的源碼
//frameworks/base/core/java/android/os/Parcel.java 1686行
/**
* Read an object from the parcel at the current dataPosition().
* 在當(dāng)前的 dataPosition()位置上讀取一個(gè)對(duì)象
*/
public final IBinder readStrongBinder() {
return nativeReadStrongBinder(mNativePtr);
}
private static native IBinder nativeReadStrongBinder(long nativePtr);
其實(shí)它內(nèi)部是調(diào)用的是nativeReadStrongBinder()方法虽界,通過上面的源碼我們知道nativeReadStrongBinder是一個(gè)native的方法,所以通過JNI調(diào)用到android_os_Parcel_readStrongBinder這個(gè)函數(shù)
3.1涛菠、android_os_Parcel_readStrongBinder()函數(shù)
//frameworks/base/core/jni/android_os_Parcel.cpp 429行
static jobject android_os_Parcel_readStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr)
{
Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
if (parcel != NULL) {
return javaObjectForIBinder(env, parcel->readStrongBinder());
}
return NULL;
}
javaObjectForIBinder將native層BpBinder對(duì)象轉(zhuǎn)換為Java層的BinderProxy對(duì)象莉御。
上面的函數(shù)中,調(diào)用了readStrongBinder()函數(shù)
3.2俗冻、readStrongBinder()函數(shù)
//frameworks/native/libs/binder/Parcel.cpp 1334行
sp<IBinder> Parcel::readStrongBinder() const
{
sp<IBinder> val;
unflatten_binder(ProcessState::self(), *this, &val);
return val;
}
這里面也很簡單礁叔,主要是調(diào)用unflatten_binder()函數(shù)
3.3、unflatten_binder()函數(shù)
//frameworks/native/libs/binder/Parcel.cpp 293行
status_t unflatten_binder(const sp<ProcessState>& proc,
const Parcel& in, sp<IBinder>* out)
{
const flat_binder_object* flat = in.readObject(false);
if (flat) {
switch (flat->type) {
case BINDER_TYPE_BINDER:
*out = reinterpret_cast<IBinder*>(flat->cookie);
return finish_unflatten_binder(NULL, *flat, in);
case BINDER_TYPE_HANDLE:
//進(jìn)入該分支
*out = proc->getStrongProxyForHandle(flat->handle);
//創(chuàng)建BpBinder對(duì)象
return finish_unflatten_binder(
static_cast<BpBinder*>(out->get()), *flat, in);
}
}
return BAD_TYPE;
}
PS:在/frameworks/native/libs/binder/Parcel.cpp/frameworks/native/libs/binder/Parcel.cpp 里面有兩個(gè)unflatten_binder()函數(shù)迄薄,其中區(qū)別點(diǎn)是琅关,最后一個(gè)入?yún)ⅲ粋€(gè)是sp<IBinder>* out讥蔽,另一個(gè)是wp<IBinder>* out涣易。大家別弄差了。
在unflatten_binder里面進(jìn)入 case BINDER_TYPE_HANDLE: 分支冶伞,然后執(zhí)行g(shù)etStrongProxyForHandle()函數(shù)新症。
3.4、getStrongProxyForHandle()函數(shù)
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
sp<IBinder> result;
AutoMutex _l(mLock);
//查找handle對(duì)應(yīng)的資源項(xiàng)
handle_entry* e = lookupHandleLocked(handle);
if (e != NULL) {
IBinder* b = e->binder;
if (b == NULL || !e->refs->attemptIncWeak(this)) {
...
//當(dāng)handle值所對(duì)應(yīng)的IBinder不存在或弱引用無效時(shí)响禽,則創(chuàng)建BpBinder對(duì)象
b = new BpBinder(handle);
e->binder = b;
if (b) e->refs = b->getWeakRefs();
result = b;
} else {
result.force_set(b);
e->refs->decWeak(this);
}
}
return result;
}
經(jīng)過該方法徒爹,最終創(chuàng)建了指向Binder服務(wù)端的BpBinder代理對(duì)象。所以說javaObjectForIBinder將native層的BpBinder對(duì)象轉(zhuǎn)化為Java層BinderProxy對(duì)象金抡。也就是說通過getService()最終取得了指向目標(biāo)Binder服務(wù)器的代理對(duì)象BinderProxy。
4腌且、總結(jié)
所以說getService的核心過程:
public static IBinder getService(String name) {
...
//此處還需要將Java層的Parcel轉(zhuǎn)化為Native層的Parcel
Parcel reply = Parcel.obtain();
// 與Binder驅(qū)動(dòng)交互
BpBinder::transact(GET_SERVICE_TRANSACTION, *data, reply, 0);
IBinder binder = javaObjectForIBinder(env, new BpBinder(handle));
...
}
javaObjectForIBinder作用是創(chuàng)建BinderProxy對(duì)象梗肝,并將BpBinder對(duì)象的地址保存到BinderProxy對(duì)象的mObjects中,獲取服務(wù)過程就是通過BpBinder來發(fā)送GET_SERVICE_TRANSACTION命令铺董,實(shí)現(xiàn)與binder驅(qū)動(dòng)進(jìn)行數(shù)據(jù)交互巫击。