該文章是一個系列文章,是本人在Android開發的漫漫長途上的一點感想和記錄,我會盡可能按照先易後難的順序進行編寫該系列。該系列引用了《Android開發藝術探索》以及《深刻理解Android 卷Ⅰ,Ⅱ,Ⅲ》中的相關知識,另外也借鑑了其餘的優質博客,在此向各位大神表示感謝,膜拜!!!另外,本系列文章知識可能須要有必定Android開發基礎和項目經驗的同窗才能更好理解,也就是說該系列文章面向的是Android中高級開發工程師。java
咱們在上一篇中比較詳盡的介紹了Android的消息機制,不過有一些內容咱們在不理解Android Binder的話是沒法講解清楚的。對於初學Android的朋友而言,最難卻又最想掌握的恐怕就是Binder機制了,由於Android系統基本上能夠看做是一個基於Binder通訊的C/S架構。 Binder就像網絡同樣,把系統的各個部分鏈接在了一塊兒,所以它是很是重要的。咱們下面會Android Binder機制進行從上到下從易到難的分層次講解,從而既能讓初學者對Binder有必定認識,也能讓有必定Android基礎的人得到收穫。
注:下文中的源碼均出自android-6.0.0_r5linux
對於初學者來講,深刻Android Binder機制是很是不明智的。Android Binder機制大都涉及Java層、Native層、驅動層這三三個方面,對於初學者來講想啃這三塊硬骨頭很容易磕着牙。咱們這這一節概述從如下幾個方面讓你從比較宏觀的角度理解Android Binder。android
在該系列博客中的第一章咱們就提及了Android進程相關問題,Android故意弱化了進程的概念,而用相對容易理解的四大組件。但是咱們在稍微深刻Android的時候,那麼進程是繞不過的。默認狀況下,同一個應用程序中的全部組件運行在同一個進程中,並且絕大多數的應用程序也都是這樣的。這個默認進程是用這個應用的包名來命名的。程序員
咱們在運行App的時候常常須要使用一些系統服務,好比剪切板服務,而剪切板服務是運行在SystemServer進程中的。那咱們的App是怎麼使用剪切板服務的呢,咱們都知道進程是相互獨立的,靜態變量等等都沒法共用。這就涉及到進程間的通訊了,即IPC。咱們都知道Android是基於Linux內核的,那咱們簡單介紹下Linux下的幾種IPC機制。面試
管道是由內核管理的一個緩衝區,至關於咱們放入內存中的一個紙條。管道的一端鏈接一個進程的輸出。這個進程會向管道中放入信息。管道的另外一端鏈接一個進程的輸入,這個進程取出被放入管道的信息。安全
命名管道是一種特殊類型的文件,它在系統中以文件形式存在。這樣克服了管道的弊端,他能夠容許沒有親緣關係的進程間通訊。服務器
共享內存是在多個進程之間共享內存區域的一種進程間的通訊方式,由IPC爲進程建立的一個特殊地址範圍,它將出如今該進程的地址空間中。其餘進程能夠將同一段共享內存鏈接到本身的地址空間中。全部進程均可以訪問共享內存中的地址,若是一個進程向共享內存中寫入了數據,所作的改動將馬上被其餘進程看到。cookie
內存映射是由一個文件到一塊內存的映射,在此以後進程操做文件,就像操做進程空間裏的內存地址同樣了。網絡
套接字機制不但能夠單機的不一樣進程通訊,並且使得跨網機器間進程能夠通訊。
套接字的建立和使用與管道是有區別的,套接字明確地將客戶端與服務器區分開來,能夠實現多個客戶端連到同一服務器。數據結構
做爲Android系統下的一種IPC機制,其本質上與上面羅列出的IPC機制並沒有本質上的不一樣,都是做爲進程間通訊的一種手段。而且在Android系統中也不是隻存在Binder這一種進程間通訊的方式,在有些地方也使用了Socket。既然Linux已經提供了衆多IPC機制,那麼Android 爲什麼還要使用Binder做爲主要的進程間通訊的方式呢,那麼固然有他的優勢存在。
Java層Binder的功能,依賴於Native層Binder來實現,能夠認爲Java層Binder架構是Native層Binder架構的一個鏡像。可是這並不影響咱們分析Android Java層Binder的功能。咱們用一個例子來講明這個過程。
咱們在第一篇中就講解了SystemServer這個進程,這個進程和zygote進程一塊兒撐起了Android 世界,他們之中有一個崩潰,Android世界就會砰然倒塌。Android許多的重要的系統服務如AMS、PMS等都運行在SystemServer進程中。可是還有一個比較重要的進程ServiceManager進程(簡稱SM)跟zygote是兄弟進程。這個進程的做用是用來統一管理服務,如AMS。它們之間的關係以下。
咱們的AMS須要向SM進程中註冊信息,其餘進程若是想使用AMS,那麼先和ServiceManager進程進行通訊查詢,接着再和AMS所在SystemServer進程通訊。這部分關係圖以下
咱們這裏僅上圖分析①②③中的一條道路,咱們來分析③,即咱們的應用進程(Client)如何與服務進程(Server)交互。
Java層的Binder,咱們來看涉及的類的結構圖
[IBinder.java]
public interface IBinder { //交互函數 public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException; }
咱們接着來看Binder和BinderProxy 他們都聲明在Binder.java中
[Binder.java]
/** Binder類 */ public class Binder implements IBinder { public final boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { ...... //這裏調用了onTransact函數進行處理,通常狀況下這個函數都會被它的子類重寫 boolean r = onTransact(code, data, reply, flags); if (reply != null) { reply.setDataPosition(0); } return r; } } /** BinderProxy類 */ final class BinderProxy implements IBinder { public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { //直接以JNI的方式調用Native層的transact函數 return transactNative(code, data, reply, flags); } public native boolean transactNative(int code, Parcel data, Parcel reply, int flags) throws RemoteException; }
通用的IPC流程以下
如今假設下面一個場景,咱們的應用進程即咱們的App想要使用ActivityManagerService的startActivity函數(這種場景確定有的,當咱們拿到手機的時候,手機已經預裝了許多App,其中Launcher App(桌面管理App)是在Android系統啓動完成以後啓動的第一個App,咱們安裝好一個應用後,點擊應用圖標即發出Intent,想要啓動另外一個App中的Activity,咱們在AndroidManifest.xml中註冊了Main Activity)。Launcher App所在的進程要與AMS所在的進程SystemServer進程交互。
咱們來看這個例子。按照上面的通用流程咱們猜想Launcher進程與SystemServer進程交互過程也如上圖所示,那麼按照這個思路咱們來看。分爲3點:
這一部分是咱們的上圖中的test函數所聲明的類或者接口,咱們的Client端代理和Server端服務都要實現這個函數。果真有
[IActivityManager.java]
public interface IActivityManager extends IInterface { public int startActivity(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int flags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException; ...... }
這裏聲明瞭咱們將要調用的業務函數startActivity,那麼接着第二點
ActivityManagerProxy是在ActivityManagerNative.java中聲明的內部類
class ActivityManagerProxy implements IActivityManager { public ActivityManagerProxy(IBinder remote) { mRemote = remote; } public IBinder asBinder() { return mRemote; } public int startActivity(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeStrongBinder(caller != null ? caller.asBinder() : null); data.writeString(callingPackage); intent.writeToParcel(data, 0); data.writeString(resolvedType); data.writeStrongBinder(resultTo); data.writeString(resultWho); data.writeInt(requestCode); data.writeInt(startFlags); if (profilerInfo != null) { data.writeInt(1); profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE); } else { data.writeInt(0); } if (options != null) { data.writeInt(1); options.writeToParcel(data, 0); } else { data.writeInt(0); } //看這裏果真是經過mRemote.transact函數,這裏的mRemote是BinderProxy類,關於這一點咱們在Native層分析的時候再給出 mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0); reply.readException(); int result = reply.readInt(); reply.recycle(); data.recycle(); return result; } ...... }
ActivityManagerNative是繼承於Binder的抽象類,並重寫了onTransact方法
public abstract class ActivityManagerNative extends Binder implements IActivityManager{ @Override public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { //根據code處理相應的業務邏輯,咱們這裏是START_ACTIVITY_TRANSACTION switch (code) { case START_ACTIVITY_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder b = data.readStrongBinder(); IApplicationThread app = ApplicationThreadNative.asInterface(b); String callingPackage = data.readString(); Intent intent = Intent.CREATOR.createFromParcel(data); String resolvedType = data.readString(); IBinder resultTo = data.readStrongBinder(); String resultWho = data.readString(); int requestCode = data.readInt(); int startFlags = data.readInt(); ProfilerInfo profilerInfo = data.readInt() != 0 ? ProfilerInfo.CREATOR.createFromParcel(data) : null; Bundle options = data.readInt() != 0 ? Bundle.CREATOR.createFromParcel(data) : null; int result = startActivity(app, callingPackage, intent, resolvedType, resultTo, resultWho, requestCode, startFlags, profilerInfo, options); reply.writeNoException(); reply.writeInt(result); return true; } } }
既然ActivityManagerNative是個抽象類,那麼誰真正實現了呢
[ActivityManagerService.java]
public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { //重寫了onTransact函數 @Override public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { ...... try { //調用父類即ActivityManagerNative的onTransact函數 return super.onTransact(code, data, reply, flags); } catch (RuntimeException e) { throw e; } } }
Launcher進程與SystemServer進程交互過程以下
關於Java層的Binder機制,咱們只須要理解以BinderProxy表明的代理端和Binder表明的服務端的概念便可,例如咱們本例中的AMS,AMS是運行在SystemServer進程中的服務端,它間接繼承於Binder,在獲得相關請求後,會調用AMS重寫的onTransact函數進行邏輯處理。那麼這個請求就是是AMS的客戶端ActivityManagerProxy經過Binder的方式發給它的,ActivityManagerProxy發送這個請求的方式,是經過調用其內部的成員變量mRemote,這個mRemote實際上是BinderProxy的對象,而後BinderProxy經過JNI調用Native層對應函數,最終經過Binder驅動達到與SystemServer交互的目的。
那麼還遺留下如下幾個問題:
1. 服務器端的代理怎麼得到的
2. 位於代理類中的mRemote這個變量
要想理解好上面的個問題,咱們必須向Native層進軍。
咱們依然以AMS分析,咱們先來想一下咱們在用戶進程中即咱們的App中想使用AMS或者其餘剪切板之類的系統服務函數了怎麼辦??按照上面的分析咱們要得到AMS的代理ActivityManagerProxy
[ActivityManagerNative.java]
//這裏咱們的App進程從SM進程獲得AMS服務對應的客戶端代理BinderProxy IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE); //以BinderProxy爲參數獲得咱們ActivityManagerProxy,並把BinderProxy對象存儲在mRemote變量中 IActivityManager am = asInterface(b); return am;
到這裏咱們就有如下問題,本小節分析1,2
1. 既然能夠經過SM得到對應的客戶端代理,那麼AMS一定已經註冊在SM中了,那麼怎麼註冊的呢?
2. AMS代理是如何得到的?
3. AMS代理是如何與Binder通訊的?
咱們來一一分析,在分析問題以前咱們先作一個假設,這個假設相當重要,那就是無論咱們的SystemServer進程與SM進程交互也好仍是咱們的App進程與SM進程也好,SM的代理已經事先建立完畢,即無論咱們在SystemServer端仍是App端,在與SM進程交互的時候不用考慮代理怎麼得到的。爲何會有如此假設,由於我本身深受其害,因爲上述三個過程均是經過Binder,很容易陷入思惟混亂。
咱們SystemServer進程中的AMS經過SM的代理與SM進程交互(讀者也能夠把這個過程想象爲你所能理解的進程間通訊方式,例如管道、Socket等),並把本身註冊在SM中
SystemServer建立出ActivityManagerService後,最終將調用其setSystemProcess方法:
[SystemServer.java]
public void setSystemProcess() { try { //註冊服務,第二個參數爲this,這裏假設SystemServer經過「socket」與SM交互 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); .......... } catch (PackageManager.NameNotFoundException e) { ........ } }
上面的請求最終是經過SM服務代理髮送的()
[ServiceManagerNative.java]
public void addService(String name, IBinder service, boolean allowIsolated) throws RemoteException { //將數據打包寫入Parcel對象 Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IServiceManager.descriptor); data.writeString(name); //注意這個地方,後文分析,此時的service爲ActivityManagerService data.writeStrongBinder(service); data.writeInt(allowIsolated ? 1 : 0); //調用BindProxy的transact函數 mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0); reply.recycle(); data.recycle(); }
上面的過程已經分析過了, 這裏咱們主要看一下哪一個對應的native層的transact函數
[android_ util_Binder.cpp]
static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj, jint code, jobject dataObj, jobject replyObj, jint flags) { ........ //將java對象轉化爲native對象 Parcel* data = parcelForJavaObject(env, dataObj); ......... Parcel* reply = parcelForJavaObject(env, replyObj); ........ //獲得native層的BpBinder IBinder* target = (IBinder*) env->GetLongField(obj, gBinderProxyOffsets.mObject); ........ //經過BpBinder利用IPCThreadState,將請求經過Binder驅動發送給SM進程 status_t err = target->transact(code, *data, reply, flags); ........ }
SM進程收到信息後便處理這個消息(這個說法並不許確,準確的說法是,SM進程中主線程一直在與binder設備交互,想必讀者也猜到了for(;;)),有消息時便經過預先定義好的函數進行處理
[service_manager.c]
switch(txn->code) { case SVC_MGR_ADD_SERVICE: s = bio_get_string16(msg, &len); if (s == NULL) { return -1; } handle = bio_get_ref(msg); allow_isolated = bio_get_uint32(msg) ? 1 : 0; //do_add_service if (do_add_service(bs, s, len, handle, txn->sender_euid, allow_isolated, txn->sender_pid)) return -1; break; } int do_add_service(struct binder_state *bs, const uint16_t *s, size_t len, uint32_t handle, uid_t uid, int allow_isolated, pid_t spid) { //結構體si,用來存儲服務信息 struct svcinfo *si; //判斷服務有沒有權限註冊,並非全部的服務都能註冊 if (!svc_can_register(s, len, spid)) { return -1; } //查詢服務有沒有註冊過 si = find_svc(s, len); if (si) {//已經註冊過 if (si->handle) { ALOGE("add_service('%s',%x) uid=%d - ALREADY REGISTERED, OVERRIDE\n", str8(s, len), handle, uid); svcinfo_death(bs, si); } si->handle = handle; } else {//尚未註冊過,咱們進入這個分支 si = malloc(sizeof(*si) + (len + 1) * sizeof(uint16_t)); if (!si) { ALOGE("add_service('%s',%x) uid=%d - OUT OF MEMORY\n", str8(s, len), handle, uid); return -1; } //保存一些handle等信息 si->handle = handle; si->len = len; memcpy(si->name, s, (len + 1) * sizeof(uint16_t)); si->name[len] = '\0'; si->death.func = (void*) svcinfo_death; si->death.ptr = si; si->allow_isolated = allow_isolated; si->next = svclist; svclist = si; } binder_acquire(bs, handle); binder_link_to_death(bs, handle, &si->death); return 0; }
看到這裏SM貌似只保留了一些AMS的信息而已,實際上並不僅是如此,咱們來看一下上面的保留問題
[Parcel.java]
data.writeStrongBinder(service); public final void writeStrongBinder(IBinder val) { //調用了native函數 nativeWriteStrongBinder(mNativePtr, val); }
跟進[android_os_Parcel.cpp]
static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr, jobject object) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); if (parcel != NULL) { //native層的parcel const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object)); if (err != NO_ERROR) { signalExceptionForError(env, clazz, err); } } } sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj) { if (obj == NULL) return NULL; //obj爲Binder類 if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) { JavaBBinderHolder* jbh = (JavaBBinderHolder*) env->GetLongField(obj, gBinderOffsets.mObject); //調用了JavaBBinderHolder的get方法 return jbh != NULL ? jbh->get(env, obj) : NULL; } //obj爲BinderProxy類 if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) { return (IBinder*) env->GetLongField(obj, gBinderProxyOffsets.mObject); } ALOGW("ibinderForJavaObject: %p is not a Binder object", obj); return NULL; }
跟進[Pacel.cpp]
status_t Parcel::writeStrongBinder(const sp<IBinder>& val) { return flatten_binder(ProcessState::self(), val, this); } 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) {//binder不爲空 IBinder *local = binder->localBinder();//是否是本地binder,本地的意思是同一個進程中的調用 if (!local) { BpBinder *proxy = binder->remoteBinder(); if (proxy == NULL) { ALOGE("null proxy"); } const int32_t handle = proxy ? proxy->handle() : 0; obj.type = BINDER_TYPE_HANDLE; obj.binder = 0; /* Don't pass uninitialized stack data to a remote process */ obj.handle = handle; obj.cookie = 0; } else {//咱們這裏明顯不是 obj.type = BINDER_TYPE_BINDER; obj.binder = reinterpret_cast<uintptr_t>(local->getWeakRefs()); obj.cookie = reinterpret_cast<uintptr_t>(local); } } else {//錯誤信息 obj.type = BINDER_TYPE_BINDER; obj.binder = 0; obj.cookie = 0; } return finish_flatten_binder(binder, obj, out); }
經過上面的代碼,咱們能夠看到當一個服務進行註冊時,會將Java層的Binder對象和Native層的BBinder關聯起來,因而服務端綁定到了Native層的Binder架構。
此外,addService中打包傳入的其實不是ActivityManagerService自己,而是對應的JavaBBinder對象。
這裏對應的結構以下圖所示:
咱們上面SystemServer中的AMS已經在SM中準備好了,那咱們ServiceManager.getService(Context.ACTIVITY_SERVICE);
同樣的過程,咱們知道最終會在service_manager.c中處理
switch(txn->code) { //這裏有個case穿透,,好吧 case SVC_MGR_GET_SERVICE: case SVC_MGR_CHECK_SERVICE: s = bio_get_string16(msg, &len); if (s == NULL) { return -1; } //查詢AMS保存在SM中對應的的那個handle handle = do_find_service(bs, s, len, txn->sender_euid, txn->sender_pid); if (!handle) break; bio_put_ref(reply, handle); return 0; } 把寫入數據後的reply返回 bio_put_uint32(reply, 0);
回到咱們的調用處
[ServiceManagerNative.java]
public IBinder getService(String name) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IServiceManager.descriptor); data.writeString(name); mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0); //看這裏readStrongBinder,是否是感受跟咱們上面的writeStrongBinder感受是一對的 IBinder binder = reply.readStrongBinder(); reply.recycle(); data.recycle(); return binder; }
Parcel的readStrongBinder仍是個JNI調用
[android_ os_Parcel.cpp]
static jobject android_os_Parcel_readStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); if (parcel != NULL) { //這裏咱們看到了什麼,,看函數名字應該是爲Binder生成一個java對象吧 return javaObjectForIBinder(env, parcel->readStrongBinder()); } return NULL; }
咱們先看Pacel的readStrongBinder方法
[Parcel.cpp]
sp<IBinder> Parcel::readStrongBinder() const { sp<IBinder> val; //看到這裏,還記得writeStrongBinder中的flatten_binder,這裏是unflatten_binder unflatten_binder(ProcessState::self(), *this, &val); return val; } 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: //到這裏咱們也清楚了進入這個分支 //調用ProcessState的getStrongProxyForHandle函數 *out = proc->getStrongProxyForHandle(flat->handle); return finish_unflatten_binder( static_cast<BpBinder*>(out->get()), *flat, in); } } return BAD_TYPE; }
繼續跟進[ProcessState.cpp]
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle) { sp<IBinder> result; AutoMutex _l(mLock); handle_entry* e = lookupHandleLocked(handle); if (e != NULL) { IBinder* b = e->binder; if (b == NULL || !e->refs->attemptIncWeak(this)) { if (handle == 0) {//這裏handle爲0的狀況是爲SM準備的, Parcel data; status_t status = IPCThreadState::self()->transact( 0, IBinder::PING_TRANSACTION, data, NULL, 0); if (status == DEAD_OBJECT) return NULL; } //咱們的不爲0,在這裏建立了BpBinder 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; }
好了剩下最後一個了javaObjectForIBinder
[android_ util_Binder.cpp]
jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val) { if (val == NULL) return NULL; //若是val是Binder對象,進入下面分支,此時val是BpBinder if (val->checkSubclass(&gBinderOffsets)) { // One of our own! jobject object = static_cast<JavaBBinder*>(val.get())->object(); LOGDEATH("objectForBinder %p: it's our own %p!\n", val.get(), object); return object; } ......... //調用BpBinder的findObject函數 //在Native層的BpBinder中有一個ObjectManager,它用來管理在Native BpBinder上建立的Java BinderProxy對象 //findObject用於判斷gBinderProxyOffsets中,是否存儲了已經被ObjectManager管理的Java BinderProxy對象 jobject object = (jobject)val->findObject(&gBinderProxyOffsets); if (object != NULL) { jobject res = jniGetReferent(env, object); ............ //若是該Java BinderProxy已經被管理,則刪除這個舊的BinderProxy android_atomic_dec(&gNumProxyRefs); val->detachObject(&gBinderProxyOffsets); env->DeleteGlobalRef(object); } //建立一個新的BinderProxy對象 object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor); if (object != NULL) { // The proxy holds a reference to the native object. env->SetLongField(object, gBinderProxyOffsets.mObject, (jlong)val.get()); val->incStrong((void*)javaObjectForIBinder); // The native object needs to hold a weak reference back to the // proxy, so we can retrieve the same proxy if it is still active. jobject refObject = env->NewGlobalRef( env->GetObjectField(object, gBinderProxyOffsets.mSelf)); //新建立的BinderProxy對象註冊到BpBinder的ObjectManager中,同時註冊一個回收函數proxy_cleanup //當BinderProxy對象detach時,proxy_cleanup函數將被調用,以釋放一些資源 val->attachObject(&gBinderProxyOffsets, refObject, jnienv_to_javavm(env), proxy_cleanup); // Also remember the death recipients registered on this proxy sp<DeathRecipientList> drl = new DeathRecipientList; drl->incStrong((void*)javaObjectForIBinder); //將死亡通知list和BinderProxy聯繫起來 env->SetLongField(object, gBinderProxyOffsets.mOrgue, reinterpret_cast<jlong>(drl.get())); // Note that a new object reference has been created. android_atomic_inc(&gNumProxyRefs); //垃圾回收相關;利用gNumRefsCreated記錄建立出的BinderProxy數量 //當建立出的BinderProxy數量大於200時,該函數將利用BinderInternal的ForceGc函數進行一個垃圾回收 incRefsCreated(env); return object; } }
到這裏總算都打通了整體流程以下
經過Java層的服務端代理最終調用到BpBinder.transact函數
[BpBinder.cpp]
status_t BpBinder:transact(uint32_t code,const Parcel&data,Parcel*reply,uint32_t flags){ if(mAlive){ //BpBinder把transact工做交給了IPCThreadState。 status_t status=IPCThreadState:self()->transact( mHandle,code,data,reply,flags);//mHandle也是參數 if(status==DEAD_OBJECT)mAlive=0; return status; } return DEAD_OBJECT; }
[IPCThreadState.cpp]
IPCThreadState::IPCThreadState() : mProcess(ProcessState::self()), mMyThreadId(gettid()), mStrictModePolicy(0), mLastTransactionBinderFlags(0) { pthread_setspecific(gTLS, this); clearCaller(); //mIn和mOut是兩個Parcel。 把它當作是發送和接收命令的緩衝區便可。 mIn.setDataCapacity(256); mOut.setDataCapacity(256); } status_t IPCThreadState::transact(int32_t handle, uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { ...... /* 注意這裏的第一個參數BC_TRANSACTION,它是應用程序向binder設備發送消息的消 息碼,而binder設備嚮應用程序回覆消息的消息碼以BR_開頭。 消息碼的定義在 binder_module.h中,請求消息碼和迴應消息碼的對應關係,須要查看Binder驅動的實 現才能將其理清楚,咱們這裏暫時用不上。 */ err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL); ...... err = waitForResponse(NULL, NULL); ...... return err; } status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags, int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer) { //binder_transaction_data是和binder設備通訊的數據結構。 binder_transaction_data tr; //果真,handle的值傳遞給了target,用來標識目的端,其中0是ServiceManager的標誌。 tr.target.handle=handle; //code是消息碼,是用來switch/case的! tr.code = code; tr.flags = binderFlags; tr.cookie = 0; tr.sender_pid = 0; tr.sender_euid = 0; const status_t err = data.errorCheck(); if (err == NO_ERROR) { tr.data_size = data.ipcDataSize(); tr.data.ptr.buffer = data.ipcData(); tr.offsets_size = data.ipcObjectsCount()*sizeof(binder_size_t); tr.data.ptr.offsets = data.ipcObjects(); } else if (statusBuffer) { tr.flags |= TF_STATUS_CODE; *statusBuffer = err; tr.data_size = sizeof(status_t); tr.data.ptr.buffer = reinterpret_cast<uintptr_t>(statusBuffer); tr.offsets_size = 0; tr.data.ptr.offsets = 0; } else { return (mLastError = err); } //把命令寫到mOut中,而不是直接發出去,可見這個函數有點名存實亡。 mOut.writeInt32(cmd); mOut.write(&tr, sizeof(tr)); return NO_ERROR; } status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult) { uint32_t cmd; int32_t err; while (1) { if ((err=talkWithDriver()) <NO_ERROR) break; err = mIn.errorCheck(); if (err < NO_ERROR) break; if (mIn.dataAvail() == 0) continue; //看見沒?這裏開始操做mIn了,看來talkWithDriver中 //把mOut發出去,而後從driver中讀到數據放到mIn中了。 cmd = mIn.readInt32(); } } status_t IPCThreadState::talkWithDriver(bool doReceive) { binder_write_read bwr; //中間東西太複雜了,不就是把mOut數據和mIn接收數據的處理後賦值給bwr嗎? status_t err; do { //用ioctl來讀寫 if (ioctl(mProcess->mDriverFD,BINDER_WRITE_READ, &bwr) >= 0) err = NO_ERROR; else err = -errno; } while (err == -EINTR); //到這裏,回覆數據就在bwr中了,bmr接收回複數據的buffer就是mIn提供的 if (bwr.read_consumed > 0) { mIn.setDataSize(bwr.read_consumed); mIn.setDataPosition(0); } return NO_ERROR; }
咱們本篇詳細分析了Binder機制,從概述->Java層Binder->Native層Binder->Binder驅動,位於各層次的讀者都能得到收穫。
很差意思各位,下週有個比較重要的面試,因此暫時不會更新該系列的博客,可是也會更新其餘博客。記錄準備面試的過程當中須要用到的比較容易錯誤的知識。
此致,敬禮