·??介紹Binder系統(tǒng)的Java層框架
·??介紹MessageQueue
·??IBinder.java
frameworks/base/core/java/android/os/IBinder.java
·??Binder.java
frameworks/base/core/java/android/os/Binder.java
·??BinderInternal.java
frameworks/base/core/java/com/android/intenal/os/BinderInternal.java
·??android_util_Binder.cpp
frameworks/base/core/jni/android_util_Binder.cpp
·??SystemServer.java
frameworks/base/services/java/com/android/servers/SystemServer.java
·??ActivityManagerService.java
frameworks/base/services/java/com/android/servers/ActivityManagerService.java
·??ServiceManager.java
frameworks/base/core/java/android/os/ServiceManager.java
·??ServcieManagerNative.java
frameworks/base/core/java/android/os/ ServcieManagerNative.java
·??MessageQueue.java
frameworks/base/core/java/android/os/MessageQueue.java
·??android_os_MessageQueue.cpp
frameworks/base/core/jni/android_os_MessageQueue.cpp
·??Looper.cpp
frameworks/base/native/android/Looper.cpp
·??Looper.h
frameworks/base/include/utils/Looper.h
·??android_app_NativeActivity.cpp
frameworks/base/core/jni/android_app_NativeActivity.cpp
以本章做為本書Android分析之旅的開篇,將重點(diǎn)關(guān)注兩個(gè)基礎(chǔ)知識(shí)點(diǎn),它們是:
·??Binder系統(tǒng)在Java世界是如何布局和工作的
·??MessageQueue的新職責(zé)
先來(lái)分析Java層中的Binder。
建議讀者先閱讀《深入理解Android:卷I》(以下簡(jiǎn)稱“卷I”)的第6章“深入理解Binder”。網(wǎng)上有樣章可下載。
如果讀者讀過(guò)卷I第6章“深入理解Binder”,相信就不會(huì)對(duì)Binder架構(gòu)中代表Client的Bp端及代表Server的Bn端感到陌生。Java層中Binder實(shí)際上也是一個(gè)C/S架構(gòu),而且其在類的命名上盡量保持與Native層一致,因此可認(rèn)為,Java層的Binder架構(gòu)是Native層Binder架構(gòu)的一個(gè)鏡像。Java層的Binder架構(gòu)中的成員如圖2-1所示。
http://wiki.jikexueyuan.com/project/deep-android-v2/images/chapter2/image001.png" alt="image" />
圖2-1 ?Java層中的Binder家族
由圖2-1可知:
·??系統(tǒng)定義了一個(gè)IBinder接口類以及DeathRecepient接口。
·??Binder類和BinderProxy類分別實(shí)現(xiàn)了IBinder接口。其中Binder類作為服務(wù)端的Bn的代表,而BinderProxy作為客戶端的Bp的代表。
·??系統(tǒng)中還定義一個(gè)BinderInternal類。該類是一個(gè)僅供Binder框架使用的類。它內(nèi)部有一個(gè)GcWatcher類,該類專門用于處理和Binder相關(guān)的垃圾回收。
·??Java層同樣提供一個(gè)用于承載通信數(shù)據(jù)的Parcel類。
注意,IBinder接口類中定義了一個(gè)叫FLAG_ONEWAY的整型,該變量的意義非常重要。當(dāng)客戶端利用Binder機(jī)制發(fā)起一個(gè)跨進(jìn)程的函數(shù)調(diào)用時(shí),調(diào)用方(即客戶端)一般會(huì)阻塞,直到服務(wù)端返回結(jié)果。這種方式和普通的函數(shù)調(diào)用是一樣的。但是在調(diào)用Binder函數(shù)時(shí),在指明了FLAG_ONEWAY標(biāo)志后,調(diào)用方只要把請(qǐng)求發(fā)送到Binder驅(qū)動(dòng)即可返回,而不用等待服務(wù)端的結(jié)果,這就是一種所謂的非阻塞方式。在Native層中,涉及的Binder調(diào)用基本都是阻塞的,但是在Java層的framework中,使用FLAG_ONEWAY進(jìn)行Binder調(diào)用的情況非常多,以后經(jīng)常會(huì)碰到。
思考 使用FLAG_ONEWAY進(jìn)行函數(shù)調(diào)用的程序在設(shè)計(jì)上有什么特點(diǎn)?這里簡(jiǎn)單分析一下:對(duì)于使用FLAG_ONEWAY的函數(shù)來(lái)說(shuō),客戶端僅向服務(wù)端發(fā)出了請(qǐng)求,但是并不能確定服務(wù)端是否處理了該請(qǐng)求。所以,客戶端一般會(huì)向服務(wù)端注冊(cè)一個(gè)回調(diào)(同樣是跨進(jìn)程的Binder調(diào)用),一旦服務(wù)端處理了該請(qǐng)求,就會(huì)調(diào)用此回調(diào)來(lái)通知客戶端處理結(jié)果。當(dāng)然,這種回調(diào)函數(shù)也大多采用FLAG_ONEWAY的方式。
雖然Java層Binder系統(tǒng)是Native層Binder系統(tǒng)的一個(gè)Mirror,但這個(gè)Mirror終歸還需借助Native層Binder系統(tǒng)來(lái)開展工作,即Mirror和Native層Binder有著千絲萬(wàn)縷的關(guān)系,一定要在Java層Binder正式工作之前建立這種關(guān)系。下面分析Java層Binder框架是如何初始化的。
在Android系統(tǒng)中,在Java初創(chuàng)時(shí)期,系統(tǒng)會(huì)提前注冊(cè)一些JNI函數(shù),其中有一個(gè)函數(shù)專門負(fù)責(zé)搭建Java Binder和Native Binder交互關(guān)系,該函數(shù)是register_android_os_Binder,代碼如下:
[-->android_util_Binder.cpp]
int register_android_os_Binder(JNIEnv* env)
{
??? //初始化Java Binder類和Native層的關(guān)系
??? if(int_register_android_os_Binder(env) < 0)
???????return -1;
??? //初始化Java BinderInternal類和Native層的關(guān)系
??? if(int_register_android_os_BinderInternal(env) < 0)
???????return -1;
?? //初始化Java BinderProxy類和Native層的關(guān)系
??? if(int_register_android_os_BinderProxy(env) < 0)
???????return -1;
?? //初始化Java Parcel類和Native層的關(guān)系
??? if(int_register_android_os_Parcel(env) < 0)
???????return -1;
??? return0;
}
據(jù)上面的代碼可知,register_android_os_Binder函數(shù)完成了Java Binder架構(gòu)中最重要的4個(gè)類的初始化工作。我們重點(diǎn)關(guān)注前3個(gè)。
int_register_android_os_Binder函數(shù)完成了Binder類的初始化工作,代碼如下:
[-->android_util_Binder.cpp]
static int int_register_android_os_Binder(JNIEnv*env)
{
? jclassclazz;
? //kBinderPathName為Java層中Binder類的全路徑名,“android/os/Binder“
? clazz =env->FindClass(kBinderPathName);
? /*
? gBinderOffSets是一個(gè)靜態(tài)類對(duì)象,它專門保存Binder類的一些在JNI層中使用的信息,
? 如成員函數(shù)execTranscat的methodID,Binder類中成員mObject的fildID
? */
???gBinderOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
???gBinderOffsets.mExecTransact
?? ??????????????????= env->GetMethodID(clazz,"execTransact", "(IIII)Z");
???gBinderOffsets.mObject
??????? ?????????????= env->GetFieldID(clazz,"mObject", "I");
?? //注冊(cè)Binder類中native函數(shù)的實(shí)現(xiàn)
??? returnAndroidRuntime::registerNativeMethods(
?????? ?????????????????????env, kBinderPathName,
??????? ????????????????????gBinderMethods,NELEM(gBinderMethods));
}
從上面代碼可知,gBinderOffsets對(duì)象保存了和Binder類相關(guān)的某些在JNI層中使用的信息。
建議 如果讀者對(duì)JNI不是很清楚,可參閱卷I第2章“深入理解JNI”。
下一個(gè)初始化的類是BinderInternal,其代碼在int_register_android_os_BinderInternal函數(shù)中。
[-->android_util_Binder.cpp]
static intint_register_android_os_BinderInternal(JNIEnv* env)
{
? ?jclass clazz;
? ?//根據(jù)BinderInternal的全路徑名找到代表該類的jclass對(duì)象。全路徑名為
? ?// “com/android/internal/os/BinderInternal”
? ?clazz =env->FindClass(kBinderInternalPathName);
? ?//gBinderInternalOffsets也是一個(gè)靜態(tài)對(duì)象,用來(lái)保存BinderInternal類的一些信息
? ?gBinderInternalOffsets.mClass = (jclass)env->NewGlobalRef(clazz);
? ?//獲取forceBinderGc的methodID
??gBinderInternalOffsets.mForceGc
?????? ??????????= env->GetStaticMethodID(clazz,"forceBinderGc", "()V");
? ???//注冊(cè)BinderInternal類中native函數(shù)的實(shí)現(xiàn)
?? ?return AndroidRuntime::registerNativeMethods(
????????????????????????env,kBinderInternalPathName,
??????? ?????????????????gBinderInternalMethods, NELEM(gBinderInternalMethods));
}
int_register_android_os_BinderInternal的工作內(nèi)容和int_register_android_os_Binder的工作內(nèi)容類似:
·??獲取一些有用的methodID和fieldID。這表明JNI層一定會(huì)向上調(diào)用Java層的函數(shù)。
·??注冊(cè)相關(guān)類中native函數(shù)的實(shí)現(xiàn)。
int_register_android_os_BinderProxy完成了BinderProxy類的初始化工作,代碼稍顯復(fù)雜,如下所示:
[-->android_util_Binder.cpp]
static intint_register_android_os_BinderProxy(JNIEnv* env)
{
??? jclassclazz;
??
? ?clazz =env->FindClass("java/lang/ref/WeakReference");
? ?//gWeakReferenceOffsets用來(lái)和WeakReference類打交道
? ?gWeakReferenceOffsets.mClass = (jclass)env->NewGlobalRef(clazz);
? ?//獲取WeakReference類get函數(shù)的MethodID
???gWeakReferenceOffsets.mGet= env->GetMethodID(clazz, "get",
?????????????????????????????????? ?"()Ljava/lang/Object;");
?? ?clazz = env->FindClass("java/lang/Error");
??? //gErrorOffsets用來(lái)和Error類打交道
???gErrorOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
?
??? clazz =env->FindClass(kBinderProxyPathName);
??? //gBinderProxyOffsets用來(lái)和BinderProxy類打交道
???gBinderProxyOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
???gBinderProxyOffsets.mConstructor= env->GetMethodID(clazz,"<init>", "()V");
??? ...... //獲取BinderProxy的一些信息
?? ?clazz =env->FindClass("java/lang/Class");
??? //gClassOffsets用來(lái)和Class類打交道
??? gClassOffsets.mGetName=env->GetMethodID(clazz,
????????????????????????????? "getName","()Ljava/lang/String;");
??? //注冊(cè)BinderProxy native函數(shù)的實(shí)現(xiàn)
??? returnAndroidRuntime::registerNativeMethods(env,
???????? ?kBinderProxyPathName,gBinderProxyMethods,
?????????????????????????????? ?NELEM(gBinderProxyMethods));
}
據(jù)上面代碼可知,int_register_android_os_BinderProxy函數(shù)除了初始化BinderProxy類外,還獲取了WeakReference類和Error類的一些信息??磥?lái)BinderProxy對(duì)象的生命周期會(huì)委托WeakReference來(lái)管理,難怪JNI層會(huì)獲取該類get函數(shù)的MethodID。
至此,Java Binder幾個(gè)重要成員的初始化已完成,同時(shí)在代碼中定義了幾個(gè)全局靜態(tài)對(duì)象,分別是gBinderOffsets、gBinderInternalOffsets和gBinderProxyOffsets。
這幾個(gè)對(duì)象的命名中都有一個(gè)Offsets,我覺(jué)得這非常別扭,不知道讀者是否有同感。
框架的初始化其實(shí)就是提前獲取一些JNI層的使用信息,如類成員函數(shù)的MethodID,類成員變量的fieldID等。這項(xiàng)工作是必需的,因?yàn)樗芄?jié)省每次使用時(shí)獲取這些信息的時(shí)間。當(dāng)Binder調(diào)用頻繁時(shí),這些時(shí)間累積起來(lái)還是不容小覷的。
下面我們通過(guò)一個(gè)例子來(lái)分析Java Binder的工作流程。
這個(gè)例子源自ActivityManagerService,我們?cè)噲D通過(guò)它揭示Java層Binder的工作原理。先來(lái)描述一下該例子的分析步驟:
·??首先分析AMS如何將自己注冊(cè)到ServiceManager。
·??然后分析AMS如何響應(yīng)客戶端的Binder調(diào)用請(qǐng)求。
本例的起點(diǎn)是setSystemProcess,其代碼如下所示:
[-->ActivityManagerService.java]
public static void setSystemProcess() {
?try {
?? ?????ActivityManagerService m = mSelf;
??????? //將ActivityManagerService服務(wù)注冊(cè)到ServiceManager中
???????ServiceManager.addService("activity", m);......
????? }
?? ......
?? return;
}
上面所示代碼行的目的是將ActivityManagerService服務(wù)加到ServiceManager中。ActivityManagerService(以后簡(jiǎn)稱AMS)是Android核心服務(wù)中的核心,我們以后會(huì)經(jīng)常和它打交道。
大家知道,整個(gè)Android系統(tǒng)中有一個(gè)Native的ServiceManager(以后簡(jiǎn)稱SM)進(jìn)程,它統(tǒng)籌管理Android系統(tǒng)上的所有Service。成為一個(gè)Service的首要條件是先在SM中注冊(cè)。下面來(lái)看Java層的Service是如何向SM注冊(cè)的。
向SM注冊(cè)服務(wù)的函數(shù)叫addService,其代碼如下:
[-->ServiceManager.java]
public static void addService(String name, IBinderservice) {
? try {
????????? //getIServiceManager返回什么
??? ?????getIServiceManager().addService(name,service);
???? }
???? ......
?}
//分析getIServiceManager函數(shù)
private static IServiceManagergetIServiceManager() {
??? ......
??? //調(diào)用asInterface,傳遞的參數(shù)類型為IBinder???????
??? sServiceManager= ServiceManagerNative.asInterface(
??????????????????????? BinderInternal.getContextObject());
??? returnsServiceManager;
}
asInterface的參數(shù)為BinderInternal.getContextObject的返回值。這是一個(gè)native的函數(shù),其實(shí)現(xiàn)的代碼為:
[-->android_util_Binder.cpp]
static jobjectandroid_os_BinderInternal_getContextObject(
JNIEnv* env, jobject clazz)
{
?? /*
?? ?下面這句代碼,我們?cè)诰鞩第6章詳細(xì)分析過(guò),它將返回一個(gè)BpProxy對(duì)象,其中
??? NULL(即0,用于標(biāo)識(shí)目的端)指定Proxy通信的目的端是ServiceManager
?? */
??? sp<IBinder>b = ProcessState::self()->getContextObject(NULL);
??? //由Native對(duì)象創(chuàng)建一個(gè)Java對(duì)象,下面分析該函數(shù)
??? returnjavaObjectForIBinder(env, b);
}
[-->android_util_Binder.cpp]
jobject javaObjectForIBinder(JNIEnv* env, constsp<IBinder>& val)
{
?? //mProxyLock是一個(gè)全局的靜態(tài)CMutex對(duì)象
??? AutoMutex_l(mProxyLock);
?
? /*
??? val對(duì)象實(shí)際類型是BpBinder,讀者可自行分析BpBinder.cpp中的findObject函數(shù)。
??? 事實(shí)上,在Native層的BpBinder中有一個(gè)ObjectManager,它用來(lái)管理在Native BpBinder
??? 上創(chuàng)建的Java BpBinder對(duì)象。下面這個(gè)findObject用來(lái)判斷gBinderProxyOffsets
??? 是否已經(jīng)保存在ObjectManager中。如果是,那就需要?jiǎng)h除這個(gè)舊的object
? */
jobject object =(jobject)val->findObject(&gBinderProxyOffsets);
??? if(object != NULL) {
???????jobject res = env->CallObjectMethod(object, gWeakReferenceOffsets.mGet);
???????android_atomic_dec(&gNumProxyRefs);
???????val->detachObject(&gBinderProxyOffsets);
???????env->DeleteGlobalRef(object);
??? }
???
??? ?//創(chuàng)建一個(gè)新的BinderProxy對(duì)象,并注冊(cè)到Native BpBinder對(duì)象的ObjectManager中
??????? object= env->NewObject(gBinderProxyOffsets.mClass,
??????????????????????????? gBinderProxyOffsets.mConstructor);
??? if(object != NULL) {
???????env->SetIntField(object, gBinderProxyOffsets.mObject,(int)val.get());
???????val->incStrong(object);
???????jobject refObject = env->NewGlobalRef(
???????????????env->GetObjectField(object, gBinderProxyOffsets.mSelf));
??????? /*
??????? 將這個(gè)新創(chuàng)建的BinderProxy對(duì)象注冊(cè)(attach)到BpBinder的ObjectManager中,
???????同時(shí)注冊(cè)一個(gè)回收函數(shù)proxy_cleanup。當(dāng)BinderProxy對(duì)象撤銷(detach)的時(shí)候,
??????? 該函數(shù)會(huì) 被調(diào)用,以釋放一些資源。讀者可自行研究proxy_cleanup函數(shù)。
????? */
???????val->attachObject(&gBinderProxyOffsets, refObject,
?????????????????????????????jnienv_to_javavm(env),proxy_cleanup);
?
??????? //DeathRecipientList保存了一個(gè)用于死亡通知的list
??????? sp<DeathRecipientList>drl = new DeathRecipientList;
???????drl->incStrong((void*)javaObjectForIBinder);
??????? //將死亡通知list和BinderProxy對(duì)象聯(lián)系起來(lái)
???????env->SetIntField(object, gBinderProxyOffsets.mOrgue,
???????????????????????????? reinterpret_cast<jint>(drl.get()));
??????? //增加該P(yáng)roxy對(duì)象的引用計(jì)數(shù)
?????? ?android_atomic_inc(&gNumProxyRefs);
??????? //下面這個(gè)函數(shù)用于垃圾回收。創(chuàng)建的Proxy對(duì)象一旦超過(guò)200個(gè),該函數(shù)
??????? //將調(diào)用BinderInter類的ForceGc做一次垃圾回收
???????incRefsCreated(env);
??? }
?
??? returnobject;
}
BinderInternal.getContextObject的代碼有點(diǎn)多,簡(jiǎn)單整理一下,可知該函數(shù)完成了以下兩個(gè)工作:
·??創(chuàng)建了一個(gè)Java層的BinderProxy對(duì)象。
·??通過(guò)JNI,該BinderProxy對(duì)象和一個(gè)Native的BpProxy對(duì)象掛鉤,而該BpProxy對(duì)象的通信目標(biāo)就是ServiceManager。
大家還記得在Native層Binder中那個(gè)著名的interface_cast宏嗎?在Java層中,雖然沒(méi)有這樣的宏,但是定義了一個(gè)類似的函數(shù)asInterface。下面來(lái)分析ServiceManagerNative類的asInterface函數(shù),其代碼如下:
[-->ServiceManagerNative.java]
static public IServiceManager asInterface(IBinderobj)
?{
???????...... //以obj為參數(shù),創(chuàng)建一個(gè)ServiceManagerProxy對(duì)象
???????return new ServiceManagerProxy(obj);
?}
上面代碼和Native層interface_cast非常類似,都是以一個(gè)BpProxy對(duì)象為參數(shù)構(gòu)造一個(gè)和業(yè)務(wù)相關(guān)的Proxy對(duì)象,例如這里的ServiceManagerProxy對(duì)象。ServiceManagerProxy對(duì)象的各個(gè)業(yè)務(wù)函數(shù)會(huì)將相應(yīng)請(qǐng)求打包后交給BpProxy對(duì)象,最終由BpProxy對(duì)象發(fā)送給Binder驅(qū)動(dòng)以完成一次通信。
提示 實(shí)際上BpProxy也不會(huì)和Binder驅(qū)動(dòng)交互,真正和Binder驅(qū)動(dòng)交互的是IPCThreadState。
現(xiàn)在來(lái)分析ServiceManagerProxy的addService函數(shù),其代碼如下:
[-->ServcieManagerNative.java]
public void addService(String name, IBinderservice)
??????????? ???????????????throws RemoteException {
???????Parcel data = Parcel.obtain();
???????Parcel reply = Parcel.obtain();
???????data.writeInterfaceToken(IServiceManager.descriptor);
???????data.writeString(name);
??????? //注意下面這個(gè)writeStrongBinder函數(shù),后面我們會(huì)詳細(xì)分析它
???????data.writeStrongBinder(service);
???????//mRemote實(shí)際上就是BinderProxy對(duì)象,調(diào)用它的transact,將封裝好的請(qǐng)求數(shù)據(jù)
?????? //發(fā)送出去
???????mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
???????reply.recycle();
???????data.recycle();
}
BinderProxy的transact,是一個(gè)native函數(shù),其實(shí)現(xiàn)函數(shù)的代碼如下所示:
[-->android_util_Binder.cpp]
static jbooleanandroid_os_BinderProxy_transact(JNIEnv* env, jobject obj,
???????????????????????????????????????????jintcode, jobject dataObj,
???????????????????????????????????????????jobject replyObj, jint flags)
{
??????? ......
??? //從Java的Parcel對(duì)象中得到Native的Parcel對(duì)象
??? Parcel*data = parcelForJavaObject(env, dataObj);
??? if (data== NULL) {
???????return JNI_FALSE;
??? }
??? //得到一個(gè)用于接收回復(fù)的Parcel對(duì)象
??? Parcel*reply = parcelForJavaObject(env, replyObj);
??? if(reply == NULL && replyObj != NULL) {
???????return JNI_FALSE;
??? }
??? //從Java的BinderProxy對(duì)象中得到之前已經(jīng)創(chuàng)建好的那個(gè)Native的BpBinder對(duì)象
??? IBinder*target = (IBinder*)
???????env->GetIntField(obj, gBinderProxyOffsets.mObject);
??? ......
??? //通過(guò)Native的BpBinder對(duì)象,將請(qǐng)求發(fā)送給ServiceManager
??? status_terr = target->transact(code, *data, reply, flags);
?? ?......
?? ?signalExceptionForError(env, obj, err);
??? returnJNI_FALSE;
}
看了上面的代碼會(huì)發(fā)現(xiàn),Java層的Binder最終還是要借助Native的Binder進(jìn)行通信的。
關(guān)于Binder這套架構(gòu),筆者有一個(gè)體會(huì)愿和讀者一起討論分析。
從架構(gòu)的角度看,在Java中搭建了一整套框架,如IBinder接口,Binder類和BinderProxy類。但是從通信角度看,不論架構(gòu)的編寫采用的是Native語(yǔ)言還是Java語(yǔ)言,只要把請(qǐng)求傳遞到Binder驅(qū)動(dòng)就可以了,所以通信的目的是向binder發(fā)送請(qǐng)求和接收回復(fù)。在這個(gè)目的之上,考慮到軟件的靈活性和可擴(kuò)展性,于是編寫了一個(gè)架構(gòu)。反過(guò)來(lái)說(shuō),也可以不使用架構(gòu)(即沒(méi)有使用任何接口、派生之類的東西)而直接和binder交互,例如ServiceManager作為Binder的一個(gè)核心程序,就是直接讀取/dev/binder設(shè)備,獲取并處理請(qǐng)求。從這一點(diǎn)上看,Binder的目的雖是簡(jiǎn)單的(即打開binder設(shè)備,然后讀請(qǐng)求和寫回復(fù)),但是架構(gòu)是復(fù)雜的(編寫各種接口類和封裝類等)。我們?cè)谘芯吭创a時(shí),一定要先搞清楚目的。實(shí)現(xiàn)只不過(guò)是達(dá)到該目的的一種手段和方式。脫離目的的實(shí)現(xiàn),如緣木求魚,很容易偏離事物本質(zhì)。
在對(duì)addService進(jìn)行分析時(shí),我們?cè)崾緒riteStrongBinder是一個(gè)特別的函數(shù)。那么它特別在哪里呢?
ActivityManagerService從ActivityManagerNative類派生,并實(shí)現(xiàn)了一些接口,其中和Binder的相關(guān)的只有這個(gè)ActivityManagerNative類,其原型如下:
[-->ActivityManagerNative.java]
public abstract class ActivityManagerNative
????????????????????????? extends Binder
????????????????????????? implementsIActivityManager
ActivityManagerNative從Binder派生,并實(shí)現(xiàn)了IActivityManager接口。下面來(lái)看ActivityManagerNative的構(gòu)造函數(shù):
[-->ActivityManagerNative.java]
public ActivityManagerNative() {
???????attachInterface(this, descriptor);//該函數(shù)很簡(jiǎn)單,讀者可自行分析
??? }
//這是ActivityManagerNative父類的構(gòu)造函數(shù),即Binder的構(gòu)造函數(shù)
public Binder() {
???????init();
}
Binder構(gòu)造函數(shù)中會(huì)調(diào)用native的init函數(shù),其實(shí)現(xiàn)的代碼如下:
[-->android_util_Binder.cpp]
static void android_os_Binder_init(JNIEnv* env,jobject obj)
{
??? //創(chuàng)建一個(gè)JavaBBinderHolder對(duì)象
???JavaBBinderHolder* jbh = new JavaBBinderHolder();
??? ?bh->incStrong((void*)android_os_Binder_init);
?? //將這個(gè)JavaBBinderHolder對(duì)象保存到Java Binder對(duì)象的mObject成員中
???env->SetIntField(obj, gBinderOffsets.mObject, (int)jbh);
}
從上面代碼可知,Java的Binder對(duì)象將和一個(gè)Native的JavaBBinderHolder對(duì)象相關(guān)聯(lián)。那么,JavaBBinderHolder是何方神圣呢?其定義如下:
[-->android_util_Binder.cpp]
class JavaBBinderHolder : public RefBase
{
public:
???sp<JavaBBinder> get(JNIEnv* env, jobject obj)
??? {
???????AutoMutex _l(mLock);
???????sp<JavaBBinder> b = mBinder.promote();
??????? if(b == NULL) {
??????????//創(chuàng)建一個(gè)JavaBBinder,obj實(shí)際上是Java層中的Binder對(duì)象
???????????b = new JavaBBinder(env, obj);
???????????mBinder = b;
????? ?}
???????return b;
??? }
?? ?......
private:
???Mutex?????????? mLock;
???wp<JavaBBinder> mBinder;
};
從派生關(guān)系上可以發(fā)現(xiàn),JavaBBinderHolder僅從RefBase派生,所以它不屬于Binder家族。Java層的Binder對(duì)象為什么會(huì)和Native層的一個(gè)與Binder家族無(wú)關(guān)的對(duì)象綁定呢?仔細(xì)觀察JavaBBinderHolder的定義可知:JavaBBinderHolder類的get函數(shù)中創(chuàng)建了一個(gè)JavaBBinder對(duì)象,這個(gè)對(duì)象就是從BnBinder派生的。
那么,這個(gè)get函數(shù)是在哪里調(diào)用的?答案在下面這句代碼中:
//其中,data是Parcel對(duì)象,service此時(shí)還是ActivityManagerService
data.writeStrongBinder(service);
writeStrongBinder會(huì)做一個(gè)替換工作,下面是它的native代碼實(shí)現(xiàn):
[-->android_util_Binder.cpp]
static void android_os_Parcel_writeStrongBinder(JNIEnv*env,
?????????????????????????????????????????????? jobjectclazz, jobject object)
{
?? //parcel是一個(gè)Native的對(duì)象,writeStrongBinder的真正參數(shù)是
?//ibinderForJavaObject的返回值
? conststatus_t err = parcel->writeStrongBinder(
??????????????????????????????????? ibinderForJavaObject(env,object));
}
[-->android_util_Binder.cpp]
sp<IBinder> ibinderForJavaObject(JNIEnv*env, jobject obj)
{
?? //如果Java的obj是Binder類,則首先獲得JavaBBinderHolder對(duì)象,然后調(diào)用
? //它的get函數(shù)。而這個(gè)get將返回一個(gè)JavaBBinder
? if(env->IsInstanceOf(obj, gBinderOffsets.mClass)) {
???? JavaBBinderHolder*jbh = (JavaBBinderHolder*)env->GetIntField(obj,
????????????????????????????????????? gBinderOffsets.mObject);
???????return jbh != NULL ? jbh->get(env, obj) : NULL;
??? }
??? //如果obj是BinderProxy類,則返回Native的BpBinder對(duì)象
??? if(env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {
???????return (IBinder*)
???????????env->GetIntField(obj, gBinderProxyOffsets.mObject);
??? }
?? returnNULL;
}
根據(jù)上面的介紹會(huì)發(fā)現(xiàn),addService實(shí)際添加到Parcel的并不是AMS本身,而是一個(gè)叫JavaBBinder的對(duì)象。正是將它最終傳遞到Binder驅(qū)動(dòng)。
讀者此時(shí)容易想到,Java層中所有的Binder對(duì)應(yīng)的都是這個(gè)JavaBBinder。當(dāng)然,不同的Binder對(duì)象對(duì)應(yīng)不同的JavaBBinder對(duì)象。
圖2-2展示了Java Binder、JavaBBinderHolder和JavaBBinder的關(guān)系。
http://wiki.jikexueyuan.com/project/deep-android-v2/images/chapter2/image002.png" alt="image" />
圖2-2 JavaBinder、JavaBBinderHolder和JavaBBinder三者的關(guān)系
從圖2-2可知:
·??Java層的Binder通過(guò)mObject指向一個(gè)Native層的JavaBBInderHolder對(duì)象。
·??Native層的JavaBBinderHolder對(duì)象通過(guò)mBinder成員變量指向一個(gè)Native的JavaBBinder對(duì)象。
·??Native的JavaBBinder對(duì)象又通過(guò)mObject變量指向一個(gè)Java層的Binder對(duì)象。
為什么不直接讓Java層的Binder對(duì)象指向Native層的JavaBBinder對(duì)象呢?由于缺乏設(shè)計(jì)文檔,這里不便妄加揣測(cè),但從JavaBBinderHolder的實(shí)現(xiàn)上來(lái)分析,估計(jì)和垃圾回收(內(nèi)存管理)有關(guān),因?yàn)镴avaBBinderHolder中的mBinder對(duì)象的類型被定義成弱引用wp了。
建議 對(duì)此,如果讀者有更好的解釋,不妨與大家分享一下。
初見(jiàn)JavaBBinde時(shí),多少有些吃驚?;叵胍幌翹ative層的Binder架構(gòu):雖然在代碼中調(diào)用的是Binder類提供的接口,但其對(duì)象卻是一個(gè)實(shí)際的服務(wù)端對(duì)象,例如MediaPlayerService對(duì)象,AudioFlinger對(duì)象。
而Java層的Binder架構(gòu)中,JavaBBinder卻是一個(gè)和業(yè)務(wù)完全無(wú)關(guān)的對(duì)象。那么,這個(gè)對(duì)象如何實(shí)現(xiàn)不同業(yè)務(wù)呢?
為回答此問(wèn)題,我們必須看它的onTransact函數(shù)。當(dāng)收到請(qǐng)求時(shí),系統(tǒng)會(huì)調(diào)用這個(gè)函數(shù)。
關(guān)于這個(gè)問(wèn)題,建議讀者閱讀卷I第六章《深入理解Binder》。
[-->android_util_Binder.cpp]
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();
???????.......
?????? //調(diào)用Java層Binder對(duì)象的execTranscat函數(shù)
???????jboolean res = env->CallBooleanMethod(mObject,
????????????????????gBinderOffsets.mExecTransact,code,
???????????????????(int32_t)&data,(int32_t)reply, flags);
??????? ......
???????return res != JNI_FALSE ? NO_ERROR : UNKNOWN_TRANSACTION;
}
就本例而言,上面代碼中的mObject就是ActivityManagerService,現(xiàn)在調(diào)用它的execTransact函數(shù),該函數(shù)在Binder類中實(shí)現(xiàn),具體代碼如下:
?[-->Binder.java]
private boolean execTransact(int code, intdataObj, int replyObj,int flags) {
???????Parcel data = Parcel.obtain(dataObj);
???????Parcel reply = Parcel.obtain(replyObj);
???????boolean res;
??????? try{
???????????//調(diào)用onTransact函數(shù),派生類可以重新實(shí)現(xiàn)這個(gè)函數(shù),以完成業(yè)務(wù)功能
???????????res = onTransact(code, data, reply, flags);
??????? }......
???????reply.recycle();
???????data.recycle();
???????return res;
??? }
}
ActivityManagerNative類實(shí)現(xiàn)了onTransact函數(shù),代碼如下:
[-->ActivityManagerNative.java]
public boolean onTransact(int code, Parcel data,Parcel reply, int flags)
???????????throws RemoteException {
???????switch (code) {
??????? caseSTART_ACTIVITY_TRANSACTION:
??????? {
???????????data.enforceInterface(IActivityManager.descriptor);
???????????IBinder b = data.readStrongBinder();
???????????......
?????????? //再由ActivityManagerService實(shí)現(xiàn)業(yè)務(wù)函數(shù)startActivity
?????????? intresult = startActivity(app, intent, resolvedType,
???????????????????grantedUriPermissions, grantedMode, resultTo, resultWho,
???????????????????requestCode, onlyIfNeeded, debug, profileFile,
???????????????????profileFd, autoStopProfiler);
???????????reply.writeNoException();
???????????reply.writeInt(result);
???????????return true;
}
由此可以看出,JavaBBinder僅是一個(gè)傳聲筒,它本身不實(shí)現(xiàn)任何業(yè)務(wù)函數(shù),其工作是:
·??當(dāng)它收到請(qǐng)求時(shí),只是簡(jiǎn)單地調(diào)用它所綁定的Java層Binder對(duì)象的exeTransact。
·??該Binder對(duì)象的exeTransact調(diào)用其子類實(shí)現(xiàn)的onTransact函數(shù)。
·??子類的onTransact函數(shù)將業(yè)務(wù)又派發(fā)給其子類來(lái)完成。請(qǐng)讀者務(wù)必注意其中的多層繼承關(guān)系。
通過(guò)這種方式,來(lái)自客戶端的請(qǐng)求就能傳遞到正確的Java Binder對(duì)象了。圖2-3展示AMS響應(yīng)請(qǐng)求的整個(gè)流程。
http://wiki.jikexueyuan.com/project/deep-android-v2/images/chapter2/image003.png" alt="image" />
圖2-3? AMS響應(yīng)請(qǐng)求的流程
圖2-3中,右上角的大方框表示AMS這個(gè)對(duì)象,其間的虛線箭頭表示調(diào)用子類重載的函數(shù)。
圖2-4展示了Java層的Binder架構(gòu)。
http://wiki.jikexueyuan.com/project/deep-android-v2/images/chapter2/image004.png" alt="image" />
圖 2-4? Java層Binder架構(gòu)
?根據(jù)圖2-4可知:
·??對(duì)于代表客戶端的BinderProxy來(lái)說(shuō),Java層的BinderProxy在Native層對(duì)應(yīng)一個(gè)BpBinder對(duì)象。凡是從Java層發(fā)出的請(qǐng)求,首先從Java層的BinderProxy傳遞到Native層的BpBinder,繼而由BpBinder將請(qǐng)求發(fā)送到Binder驅(qū)動(dòng)。
·??對(duì)于代表服務(wù)端的Service來(lái)說(shuō),Java層的Binder在Native層有一個(gè)JavaBBinder對(duì)象。前面介紹過(guò),所有Java層的Binder在Native層都對(duì)應(yīng)為JavaBBinder,而JavaBBinder僅起到中轉(zhuǎn)作用,即把來(lái)自客戶端的請(qǐng)求從Native層傳遞到Java層。
·??系統(tǒng)中依然只有一個(gè)Native的ServiceManager。
至此,Java層的Binder架構(gòu)已介紹完畢。從前面的分析可以看出,Java層Binder非常依賴Native層的Binder。建議想進(jìn)一步了解Binder的讀者們,要深入了解這一問(wèn)題,有必要閱讀卷I的第6章“深入理解Binder”。
卷I第5章介紹過(guò),MessageQueue類封裝了與消息隊(duì)列有關(guān)的操作。在一個(gè)以消息驅(qū)動(dòng)的系統(tǒng)中,最重要的兩部分就是消息隊(duì)列和消息處理循環(huán)。在Andrid 2.3以前,只有Java世界的居民有資格向MessageQueue中添加消息以驅(qū)動(dòng)Java世界的正常運(yùn)轉(zhuǎn),但從Android 2.3開始,MessageQueue的核心部分下移至Native層,讓Native世界的居民也能利用消息循環(huán)來(lái)處理他們所在世界的事情。因此現(xiàn)在的MessageQueue心系Native和Java兩個(gè)世界。
現(xiàn)在來(lái)分析MessageQueue是如何跨界工作的,其代碼如下:
[-->MessageQueue.java]
?MessageQueue() {
???????nativeInit(); //構(gòu)造函數(shù)調(diào)用nativeInit,該函數(shù)由Native層實(shí)現(xiàn)
?}
nativeInit函數(shù)的真正實(shí)現(xiàn)為android_os_MessageQueue_nativeInit,其代碼如下:
[-->android_os_MessageQueue.cpp]
static voidandroid_os_MessageQueue_nativeInit(JNIEnv* env, jobject obj) {
?? //NativeMessageQueue是MessageQueue在Native層的代表
?? NativeMessageQueue*nativeMessageQueue = new NativeMessageQueue();
?? ......
?? //將這個(gè)NativeMessageQueue對(duì)象設(shè)置到Java層保存
?? android_os_MessageQueue_setNativeMessageQueue(env,obj,
?????????????????????????????????????????????????????????nativeMessageQueue);
}
?nativeInit函數(shù)在Native層創(chuàng)建了一個(gè)與MessageQueue對(duì)應(yīng)的NativeMessageQueue對(duì)象,其構(gòu)造函數(shù)如下:
[-->android_os_MessageQueue.cpp]
NativeMessageQueue::NativeMessageQueue() {
?/*
?? 代表消息循環(huán)的Looper也在Native層中呈現(xiàn)身影了。根據(jù)消息驅(qū)動(dòng)的知識(shí),一個(gè)線程會(huì)有一個(gè)
?? Looper來(lái)循環(huán)處理消息隊(duì)列中的消息。下面一行的調(diào)用就是取得保存在線程本地存儲(chǔ)空間
?? (Thread Local Storage)中的Looper對(duì)象
?? */
??? mLooper= Looper::getForThread();
?? if(mLooper == NULL) {
??? /*
???? 如為第一次進(jìn)來(lái),則該線程沒(méi)有設(shè)置本地存儲(chǔ),所以須先創(chuàng)建一個(gè)Looper,然后再將其保存到
???? TLS中,這是很常見(jiàn)的一種以線程為單位的單例模式
???? */
?????mLooper = new Looper(false);
?????Looper::setForThread(mLooper);
??? }
}
Native的Looper是Native世界中參與消息循環(huán)的一位重要角色。雖然它的類名和Java層的Looper類一樣,但此二者其實(shí)并無(wú)任何關(guān)系。這一點(diǎn)以后還將詳細(xì)分析。
當(dāng)一切準(zhǔn)備就緒后,Java層的消息循環(huán)處理,也就是Looper會(huì)在一個(gè)循環(huán)中提取并處理消息。消息的提取就是調(diào)用MessageQueue的next函數(shù)。當(dāng)消息隊(duì)列為空時(shí),next就會(huì)阻塞。MessageQueue同時(shí)支持Java層和Native層的事件,那么其next函數(shù)該怎么實(shí)現(xiàn)呢?具體代碼如下:
[-->MessagQueue.java]
final Message next() {
??????? intpendingIdleHandlerCount = -1;
??????? intnextPollTimeoutMillis = 0;
?
??????? for(;;) {
?????????? ......
??????????? //mPtr保存了NativeMessageQueue的指針,調(diào)用nativePollOnce進(jìn)行等待
???????????nativePollOnce(mPtr, nextPollTimeoutMillis);
???????????synchronized (this) {
???????????????final long now = SystemClock.uptimeMillis();
???????????????//mMessages用來(lái)存儲(chǔ)消息,這里從其中取一個(gè)消息進(jìn)行處理
???????????????final Message msg = mMessages;
???????????????if (msg != null) {
???????????????????final long when = msg.when;
???????????????????if (now >= when) {
??????????????????????? mBlocked = false;
??????????????????????? mMessages = msg.next;
??????????????????????? msg.next = null;
??????????????????????? msg.markInUse();
??????????????????????? return msg; //返回一個(gè)Message給Looper進(jìn)行派發(fā)和處理
???????????????????} else {
??????????????????????? nextPollTimeoutMillis =(int) Math.min(when - now,
?????????????????????????????????????????????????????Integer.MAX_VALUE);
???????????????????}
???????????????} else {
???????????????????nextPollTimeoutMillis = -1;
???????????????}
?????????? ......
?????????? /*
?????????? 處理注冊(cè)的IdleHandler,當(dāng)MessageQueue中沒(méi)有Message時(shí),
???????????Looper會(huì)調(diào)用IdleHandler做一些工作,例如做垃圾回收等
???????????*/
???????????......
???????????pendingIdleHandlerCount = 0;
??????????nextPollTimeoutMillis = 0;
??????? }
}
看到這里,可能會(huì)有人覺(jué)得這個(gè)MessageQueue很簡(jiǎn)單,不就是從以前在Java層的wait變成現(xiàn)在Native層的wait了嗎?但是事情本質(zhì)比表象要復(fù)雜得多,來(lái)思考下面的情況:
·??nativePollOnce返回后,next函數(shù)將從mMessages中提取一個(gè)消息。也就是說(shuō),要讓nativePollOnce返回,至少要添加一個(gè)消息到消息隊(duì)列,否則nativePollOnce不過(guò)是做了一次無(wú)用功罷了。
·??如果nativePollOnce將在Native層等待,就表明Native層也可以投遞Message,但是從Message類的實(shí)現(xiàn)代碼上看,該類和Native層沒(méi)有建立任何關(guān)系。那么nativePollOnce在等待什么呢?
對(duì)于上面的問(wèn)題,相信有些讀者心中已有了答案:nativePollOnce不僅在等待Java層來(lái)的Message,實(shí)際上還在Native還做了大量的工作。
下面我們來(lái)分析Java層投遞Message并觸發(fā)nativePollOnce工作的正常流程。
MessageQueue的enqueueMessage函數(shù)完成將一個(gè)Message投遞到MessageQueue中的工作,其代碼如下:
[-->MesssageQueue.java]
final boolean enqueueMessage(Message msg, longwhen) {
?????? ?......
???????final boolean needWake;
???????synchronized (this) {
???????????if (mQuiting) {
???????????????return false;
???????????} else if (msg.target == null) {
???????????????mQuiting = true;
???????????}
???????????msg.when = when;
???????????Message p = mMessages;
???????????if (p == null || when == 0 || when < p.when) {
???????????????/*
????????????????如果p為空,表明消息隊(duì)列中沒(méi)有消息,那么msg將是第一個(gè)消息,needWake
????????????????需要根據(jù)mBlocked的情況考慮是否觸發(fā)
???????????????*/
???????????????msg.next = p;
???????????????mMessages = msg;
???????????????needWake = mBlocked;
???????????} else {
???????????????//如果p不為空,表明消息隊(duì)列中還有剩余消息,需要將新的msg加到消息尾
???????????????Message prev = null;
???????????????while (p != null && p.when <= when) {
???????????????????prev = p;
???????????????????p = p.next;
???????????????}
???????????????msg.next = prev.next;
???????????????prev.next = msg;
???????????????//因?yàn)橄㈥?duì)列之前還剩余有消息,所以這里不用調(diào)用nativeWakeup
???????????????needWake = false;
???????????}
??????? }
??????? if(needWake) {
???????????//調(diào)用nativeWake,以觸發(fā)nativePollOnce函數(shù)結(jié)束等待
???????????nativeWake(mPtr);
???? ???}
???????return true;
??? }
上面的代碼比較簡(jiǎn)單,主要功能是:
·??將message按執(zhí)行時(shí)間排序,并加入消息隊(duì)。
·??根據(jù)情況調(diào)用nativeWake函數(shù),以觸發(fā)nativePollOnce函數(shù),結(jié)束等待。
建議 雖然代碼簡(jiǎn)單,但是對(duì)于那些不熟悉多線程的讀者,還是要細(xì)細(xì)品味一下mBlocked值的作用。我們常說(shuō)細(xì)節(jié)體現(xiàn)美,代碼也一樣,這個(gè)小小的mBlocked正是如此。
nativeWake函數(shù)的代碼如下所示:
[-->android_os_MessageQueue.cpp]
static voidandroid_os_MessageQueue_nativeWake(JNIEnv* env, jobject obj,
??????????????????????????????????????????????????????jint ptr)
{
??? NativeMessageQueue*nativeMessageQueue =? //取出NativeMessageQueue對(duì)象
????????????????????? ?reinterpret_cast<NativeMessageQueue*>(ptr);
??? returnnativeMessageQueue->wake(); //調(diào)用它的wake函