這個例子源自ActivityManagerService,我們試圖通過它揭示Java層Binder的工作原理。先來描述一下該例子的分析步驟:
- 首先分析AMS如何將自己注冊到ServiceManager。
- 然后分析AMS如何響應客戶端的Binder調用請求。
本例的起點是setSystemProcess,其代碼如下所示:
**ActivityManagerService.java**
~~~
public static void setSystemProcess() {
try {
ActivityManagerService m = mSelf;
//將ActivityManagerService服務注冊到ServiceManager中
ServiceManager.addService("activity", m);......
}
......
return;
}
~~~
上面所示代碼行的目的是將ActivityManagerService服務加到ServiceManager中。ActivityManagerService(以后簡稱AMS)是Android核心服務中的核心,我們以后會經常和它打交道。
大家知道,整個Android系統中有一個Native的ServiceManager(以后簡稱SM)進程,它統籌管理Android系統上的所有Service。成為一個Service的首要條件是先在SM中注冊。下面來看Java層的Service是如何向SM注冊的。
1. 向ServiceManager注冊服務
(1) 創建ServiceManagerProxy
向SM注冊服務的函數叫addService,其代碼如下:
**ServiceManager.java**
~~~
public static void addService(String name, IBinderservice) {
try {
//getIServiceManager返回什么
getIServiceManager().addService(name,service);
}
......
}
//分析getIServiceManager函數
private static IServiceManagergetIServiceManager() {
......
//調用asInterface,傳遞的參數類型為IBinder
sServiceManager= ServiceManagerNative.asInterface(
BinderInternal.getContextObject());
returnsServiceManager;
}
~~~
asInterface的參數為BinderInternal.getContextObject的返回值。這是一個native的函數,其實現的代碼為:
**android_util_Binder.cpp**
~~~
static jobjectandroid_os_BinderInternal_getContextObject(
JNIEnv* env, jobject clazz)
{
/*
下面這句代碼,我們在卷I第6章詳細分析過,它將返回一個BpProxy對象,其中
NULL(即0,用于標識目的端)指定Proxy通信的目的端是ServiceManager
*/
sp<IBinder>b = ProcessState::self()->getContextObject(NULL);
//由Native對象創建一個Java對象,下面分析該函數
returnjavaObjectForIBinder(env, b);
}
~~~
**android_util_Binder.cpp**
~~~
jobject javaObjectForIBinder(JNIEnv* env, constsp<IBinder>& val)
{
//mProxyLock是一個全局的靜態CMutex對象
AutoMutex_l(mProxyLock);
/*
val對象實際類型是BpBinder,讀者可自行分析BpBinder.cpp中的findObject函數。
事實上,在Native層的BpBinder中有一個ObjectManager,它用來管理在Native BpBinder
上創建的Java BpBinder對象。下面這個findObject用來判斷gBinderProxyOffsets
是否已經保存在ObjectManager中。如果是,那就需要刪除這個舊的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);
}
//創建一個新的BinderProxy對象,并注冊到Native BpBinder對象的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));
/*
將這個新創建的BinderProxy對象注冊(attach)到BpBinder的ObjectManager中,
同時注冊一個回收函數proxy_cleanup。當BinderProxy對象撤銷(detach)的時候,
該函數會 被調用,以釋放一些資源。讀者可自行研究proxy_cleanup函數。
*/
val->attachObject(&gBinderProxyOffsets, refObject,
jnienv_to_javavm(env),proxy_cleanup);
//DeathRecipientList保存了一個用于死亡通知的list
sp<DeathRecipientList>drl = new DeathRecipientList;
drl->incStrong((void*)javaObjectForIBinder);
//將死亡通知list和BinderProxy對象聯系起來
env->SetIntField(object, gBinderProxyOffsets.mOrgue,
reinterpret_cast<jint>(drl.get()));
//增加該Proxy對象的引用計數
android_atomic_inc(&gNumProxyRefs);
//下面這個函數用于垃圾回收。創建的Proxy對象一旦超過200個,該函數
//將調用BinderInter類的ForceGc做一次垃圾回收
incRefsCreated(env);
}
returnobject;
}
~~~
BinderInternal.getContextObject的代碼有點多,簡單整理一下,可知該函數完成了以下兩個工作:
- 創建了一個Java層的BinderProxy對象。
- 通過JNI,該BinderProxy對象和一個Native的BpProxy對象掛鉤,而該BpProxy對象的通信目標就是ServiceManager。
大家還記得在Native層Binder中那個著名的interface_cast宏嗎?在Java層中,雖然沒有這樣的宏,但是定義了一個類似的函數asInterface。下面來分析ServiceManagerNative類的asInterface函數,其代碼如下:
**ServiceManagerNative.java**
~~~
static public IServiceManager asInterface(IBinderobj)
{
...... //以obj為參數,創建一個ServiceManagerProxy對象
return new ServiceManagerProxy(obj);
}
~~~
上面代碼和Native層interface_cast非常類似,都是以一個BpProxy對象為參數構造一個和業務相關的Proxy對象,例如這里的ServiceManagerProxy對象。ServiceManagerProxy對象的各個業務函數會將相應請求打包后交給BpProxy對象,最終由BpProxy對象發送給Binder驅動以完成一次通信。
>[info] **提示 **實際上BpProxy也不會和Binder驅動交互,真正和Binder驅動交互的是IPCThreadState。
(2) addService函數分析
現在來分析ServiceManagerProxy的addService函數,其代碼如下:
**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);
//注意下面這個writeStrongBinder函數,后面我們會詳細分析它
data.writeStrongBinder(service);
//mRemote實際上就是BinderProxy對象,調用它的transact,將封裝好的請求數據
//發送出去
mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
reply.recycle();
data.recycle();
}
~~~
BinderProxy的transact,是一個native函數,其實現函數的代碼如下所示:
**android_util_Binder.cpp**
~~~
static jbooleanandroid_os_BinderProxy_transact(JNIEnv* env, jobject obj,
jintcode, jobject dataObj,
jobject replyObj, jint flags)
{
......
//從Java的Parcel對象中得到Native的Parcel對象
Parcel*data = parcelForJavaObject(env, dataObj);
if (data== NULL) {
return JNI_FALSE;
}
//得到一個用于接收回復的Parcel對象
Parcel*reply = parcelForJavaObject(env, replyObj);
if(reply == NULL && replyObj != NULL) {
return JNI_FALSE;
}
//從Java的BinderProxy對象中得到之前已經創建好的那個Native的BpBinder對象
IBinder*target = (IBinder*)
env->GetIntField(obj, gBinderProxyOffsets.mObject);
......
//通過Native的BpBinder對象,將請求發送給ServiceManager
status_terr = target->transact(code, *data, reply, flags);
......
signalExceptionForError(env, obj, err);
returnJNI_FALSE;
}
~~~
看了上面的代碼會發現,Java層的Binder最終還是要借助Native的Binder進行通信的。
關于Binder這套架構,筆者有一個體會愿和讀者一起討論分析。
從架構的角度看,在Java中搭建了一整套框架,如IBinder接口,Binder類和BinderProxy類。但是從通信角度看,不論架構的編寫采用的是Native語言還是Java語言,只要把請求傳遞到Binder驅動就可以了,所以通信的目的是向binder發送請求和接收回復。在這個目的之上,考慮到軟件的靈活性和可擴展性,于是編寫了一個架構。反過來說,也可以不使用架構(即沒有使用任何接口、派生之類的東西)而直接和binder交互,例如ServiceManager作為Binder的一個核心程序,就是直接讀取/dev/binder設備,獲取并處理請求。從這一點上看,Binder的目的雖是簡單的(即打開binder設備,然后讀請求和寫回復),但是架構是復雜的(編寫各種接口類和封裝類等)。我們在研究源碼時,一定要先搞清楚目的。實現只不過是達到該目的的一種手段和方式。脫離目的的實現,如緣木求魚,很容易偏離事物本質。
在對addService進行分析時,我們曾提示writeStrongBinder是一個特別的函數。那么它特別在哪里呢?
(3) 三人行之Binder、JavaBBinderHolder和JavaBBinder
ActivityManagerService從ActivityManagerNative類派生,并實現了一些接口,其中和Binder的相關的只有這個ActivityManagerNative類,其原型如下:
**ActivityManagerNative.java**
~~~
public abstract class ActivityManagerNative
extends Binder
implementsIActivityManager
~~~
ActivityManagerNative從Binder派生,并實現了IActivityManager接口。下面來看ActivityManagerNative的構造函數:
**ActivityManagerNative.java**
~~~
public ActivityManagerNative() {
attachInterface(this, descriptor);//該函數很簡單,讀者可自行分析
}
//這是ActivityManagerNative父類的構造函數,即Binder的構造函數
public Binder() {
init();
}
~~~
Binder構造函數中會調用native的init函數,其實現的代碼如下:
**android_util_Binder.cpp**
~~~
static void android_os_Binder_init(JNIEnv* env,jobject obj)
{
//創建一個JavaBBinderHolder對象
JavaBBinderHolder* jbh = new JavaBBinderHolder();
bh->incStrong((void*)android_os_Binder_init);
//將這個JavaBBinderHolder對象保存到Java Binder對象的mObject成員中
env->SetIntField(obj, gBinderOffsets.mObject, (int)jbh);
}
~~~
從上面代碼可知,Java的Binder對象將和一個Native的JavaBBinderHolder對象相關聯。那么,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) {
//創建一個JavaBBinder,obj實際上是Java層中的Binder對象
b = new JavaBBinder(env, obj);
mBinder = b;
}
return b;
}
......
private:
Mutex mLock;
wp<JavaBBinder> mBinder;
};
~~~
從派生關系上可以發現,JavaBBinderHolder僅從RefBase派生,所以它不屬于Binder家族。Java層的Binder對象為什么會和Native層的一個與Binder家族無關的對象綁定呢?仔細觀察JavaBBinderHolder的定義可知:JavaBBinderHolder類的get函數中創建了一個JavaBBinder對象,這個對象就是從BnBinder派生的。
那么,這個get函數是在哪里調用的?答案在下面這句代碼中:
~~~
//其中,data是Parcel對象,service此時還是ActivityManagerService
data.writeStrongBinder(service);
~~~
writeStrongBinder會做一個替換工作,下面是它的native代碼實現:
**android_util_Binder.cpp**
~~~
static void android_os_Parcel_writeStrongBinder(JNIEnv*env,
jobjectclazz, jobject object)
{
//parcel是一個Native的對象,writeStrongBinder的真正參數是
//ibinderForJavaObject的返回值
conststatus_t err = parcel->writeStrongBinder(
ibinderForJavaObject(env,object));
}
~~~
**android_util_Binder.cpp**
~~~
sp<IBinder> ibinderForJavaObject(JNIEnv*env, jobject obj)
{
//如果Java的obj是Binder類,則首先獲得JavaBBinderHolder對象,然后調用
//它的get函數。而這個get將返回一個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對象
if(env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {
return (IBinder*)
env->GetIntField(obj, gBinderProxyOffsets.mObject);
}
returnNULL;
}
~~~
根據上面的介紹會發現,addService實際添加到Parcel的并不是AMS本身,而是一個叫JavaBBinder的對象。正是將它最終傳遞到Binder驅動。
讀者此時容易想到,Java層中所有的Binder對應的都是這個JavaBBinder。當然,不同的Binder對象對應不同的JavaBBinder對象。
圖2-2展示了Java Binder、JavaBBinderHolder和JavaBBinder的關系。
:-: 
圖2-2 JavaBinder、JavaBBinderHolder和JavaBBinder三者的關系
從圖2-2可知:
- Java層的Binder通過mObject指向一個Native層的JavaBBInderHolder對象。
- Native層的JavaBBinderHolder對象通過mBinder成員變量指向一個Native的JavaBBinder對象。
- Native的JavaBBinder對象又通過mObject變量指向一個Java層的Binder對象。
為什么不直接讓Java層的Binder對象指向Native層的JavaBBinder對象呢?由于缺乏設計文檔,這里不便妄加揣測,但從JavaBBinderHolder的實現上來分析,估計和垃圾回收(內存管理)有關,因為JavaBBinderHolder中的mBinder對象的類型被定義成弱引用wp了。
* * * * *
**建議** 對此,如果讀者有更好的解釋,不妨與大家分享一下。
* * * * *
2. ActivityManagerService響應請求
初見JavaBBinde時,多少有些吃驚。回想一下Native層的Binder架構:雖然在代碼中調用的是Binder類提供的接口,但其對象卻是一個實際的服務端對象,例如MediaPlayerService對象,AudioFlinger對象。
而Java層的Binder架構中,JavaBBinder卻是一個和業務完全無關的對象。那么,這個對象如何實現不同業務呢?
為回答此問題,我們必須看它的onTransact函數。當收到請求時,系統會調用這個函數。
關于這個問題,建議讀者閱讀卷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();
.......
//調用Java層Binder對象的execTranscat函數
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,現在調用它的execTransact函數,該函數在Binder類中實現,具體代碼如下:
**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{
//調用onTransact函數,派生類可以重新實現這個函數,以完成業務功能
res = onTransact(code, data, reply, flags);
}......
reply.recycle();
data.recycle();
return res;
}
}
~~~
ActivityManagerNative類實現了onTransact函數,代碼如下:
**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實現業務函數startActivity
intresult = startActivity(app, intent, resolvedType,
grantedUriPermissions, grantedMode, resultTo, resultWho,
requestCode, onlyIfNeeded, debug, profileFile,
profileFd, autoStopProfiler);
reply.writeNoException();
reply.writeInt(result);
return true;
}
~~~
由此可以看出,JavaBBinder僅是一個傳聲筒,它本身不實現任何業務函數,其工作是:
- 當它收到請求時,只是簡單地調用它所綁定的Java層Binder對象的exeTransact。
- 該Binder對象的exeTransact調用其子類實現的onTransact函數。
- 子類的onTransact函數將業務又派發給其子類來完成。請讀者務必注意其中的多層繼承關系。
通過這種方式,來自客戶端的請求就能傳遞到正確的Java Binder對象了。圖2-3展示AMS響應請求的整個流程。
:-: 
圖2-3 AMS響應請求的流程
圖2-3中,右上角的大方框表示AMS這個對象,其間的虛線箭頭表示調用子類重載的函數。
- 前言
- 第1章 搭建Android源碼工作環境
- 1.1 Android系統架構
- 1.2 搭建開發環境
- 1.2.1 下載源碼
- 1.2.2 編譯源碼
- 1.2.3 利用Eclipse調試system_process
- 1.3 本章小結
- 第2章 深入理解Java Binder和MessageQueue
- 2.1 概述
- 2.2 Java層中的Binder架構分析
- 2.2.1 Binder架構總覽
- 2.2.2 初始化Java層Binder框架
- 2.2.3 addService實例分析
- 2.2.4 Java層Binder架構總結
- 2.3 心系兩界的MessageQueue
- 2.3.1 MessageQueue的創建
- 2.3.2 提取消息
- 2.3.3 nativePollOnce函數分析
- 2.3.4 MessageQueue總結
- 2.4 本章小結
- 第3章 深入理解SystemServer
- 3.1 概述
- 3.2 SystemServer分析
- 3.2.1 main函數分析
- 3.2.2 Service群英會
- 3.3 EntropyService分析
- 3.4 DropBoxManagerService分析
- 3.4.1 DBMS構造函數分析
- 3.4.2 dropbox日志文件的添加
- 3.4.3 DBMS和settings數據庫
- 3.5 DiskStatsService和DeviceStorageMonitorService分析
- 3.5.1 DiskStatsService分析
- 3.5.2 DeviceStorageManagerService分析
- 3.6 SamplingProfilerService分析
- 3.6.1 SamplingProfilerService構造函數分析
- 3.6.2 SamplingProfilerIntegration分析
- 3.7 ClipboardService分析
- 3.7.1 復制數據到剪貼板
- 3.7.2 從剪切板粘貼數據
- 3.7.3 CBS中的權限管理
- 3.8 本章小結
- 第4章 深入理解PackageManagerService
- 4.1 概述
- 4.2 初識PackageManagerService
- 4.3 PKMS的main函數分析
- 4.3.1 構造函數分析之前期準備工作
- 4.3.2 構造函數分析之掃描Package
- 4.3.3 構造函數分析之掃尾工作
- 4.3.4 PKMS構造函數總結
- 4.4 APK Installation分析
- 4.4.1 adb install分析
- 4.4.2 pm分析
- 4.4.3 installPackageWithVerification函數分析
- 4.4.4 APK 安裝流程總結
- 4.4.5 Verification介紹
- 4.5 queryIntentActivities分析
- 4.5.1 Intent及IntentFilter介紹
- 4.5.2 Activity信息的管理
- 4.5.3 Intent 匹配查詢分析
- 4.5.4 queryIntentActivities總結
- 4.6 installd及UserManager介紹
- 4.6.1 installd介紹
- 4.6.2 UserManager介紹
- 4.7 本章學習指導
- 4.8 本章小結
- 第5章 深入理解PowerManagerService
- 5.1 概述
- 5.2 初識PowerManagerService
- 5.2.1 PMS構造函數分析
- 5.2.2 init分析
- 5.2.3 systemReady分析
- 5.2.4 BootComplete處理
- 5.2.5 初識PowerManagerService總結
- 5.3 PMS WakeLock分析
- 5.3.1 WakeLock客戶端分析
- 5.3.2 PMS acquireWakeLock分析
- 5.3.3 Power類及LightService類介紹
- 5.3.4 WakeLock總結
- 5.4 userActivity及Power按鍵處理分析
- 5.4.1 userActivity分析
- 5.4.2 Power按鍵處理分析
- 5.5 BatteryService及BatteryStatsService分析
- 5.5.1 BatteryService分析
- 5.5.2 BatteryStatsService分析
- 5.5.3 BatteryService及BatteryStatsService總結
- 5.6 本章學習指導
- 5.7 本章小結
- 第6章 深入理解ActivityManagerService
- 6.1 概述
- 6.2 初識ActivityManagerService
- 6.2.1 ActivityManagerService的main函數分析
- 6.2.2 AMS的 setSystemProcess分析
- 6.2.3 AMS的 installSystemProviders函數分析
- 6.2.4 AMS的 systemReady分析
- 6.2.5 初識ActivityManagerService總結
- 6.3 startActivity分析
- 6.3.1 從am說起
- 6.3.2 AMS的startActivityAndWait函數分析
- 6.3.3 startActivityLocked分析
- 6.4 Broadcast和BroadcastReceiver分析
- 6.4.1 registerReceiver流程分析
- 6.4.2 sendBroadcast流程分析
- 6.4.3 BROADCAST_INTENT_MSG消息處理函數
- 6.4.4 應用進程處理廣播分析
- 6.4.5 廣播處理總結
- 6.5 startService之按圖索驥
- 6.5.1 Service知識介紹
- 6.5.2 startService流程圖
- 6.6 AMS中的進程管理
- 6.6.1 Linux進程管理介紹
- 6.6.2 關于Android中的進程管理的介紹
- 6.6.3 AMS進程管理函數分析
- 6.6.4 AMS進程管理總結
- 6.7 App的 Crash處理
- 6.7.1 應用進程的Crash處理
- 6.7.2 AMS的handleApplicationCrash分析
- 6.7.3 AppDeathRecipient binderDied分析
- 6.7.4 App的Crash處理總結
- 6.8 本章學習指導
- 6.9 本章小結
- 第7章 深入理解ContentProvider
- 7.1 概述
- 7.2 MediaProvider的啟動及創建
- 7.2.1 Context的getContentResolver函數分析
- 7.2.2 MediaStore.Image.Media的query函數分析
- 7.2.3 MediaProvider的啟動及創建總結
- 7.3 SQLite創建數據庫分析
- 7.3.1 SQLite及SQLiteDatabase家族
- 7.3.2 MediaProvider創建數據庫分析
- 7.3.3 SQLiteDatabase創建數據庫的分析總結
- 7.4 Cursor 的query函數的實現分析
- 7.4.1 提取query關鍵點
- 7.4.2 MediaProvider 的query分析
- 7.4.3 query關鍵點分析
- 7.4.4 Cursor query實現分析總結
- 7.5 Cursor close函數實現分析
- 7.5.1 客戶端close的分析
- 7.5.2 服務端close的分析
- 7.5.3 finalize函數分析
- 7.5.4 Cursor close函數總結
- 7.6 ContentResolver openAssetFileDescriptor函數分析
- 7.6.1 openAssetFileDescriptor之客戶端調用分析
- 7.6.2 ContentProvider的 openTypedAssetFile函數分析
- 7.6.3 跨進程傳遞文件描述符的探討
- 7.6.4 openAssetFileDescriptor函數分析總結
- 7.7 本章學習指導
- 7.8 本章小結
- 第8章 深入理解ContentService和AccountManagerService
- 8.1 概述
- 8.2 數據更新通知機制分析
- 8.2.1 初識ContentService
- 8.2.2 ContentResovler 的registerContentObserver分析
- 8.2.3 ContentResolver的 notifyChange分析
- 8.2.4 數據更新通知機制總結和深入探討
- 8.3 AccountManagerService分析
- 8.3.1 初識AccountManagerService
- 8.3.2 AccountManager addAccount分析
- 8.3.3 AccountManagerService的分析總結
- 8.4 數據同步管理SyncManager分析
- 8.4.1 初識SyncManager
- 8.4.2 ContentResolver 的requestSync分析
- 8.4.3 數據同步管理SyncManager分析總結
- 8.5 本章學習指導
- 8.6 本章小結