Binder機(jī)制是android中實(shí)現(xiàn)的進(jìn)程間通信的架構(gòu),它采用的是c/s架構(gòu),client通過代理完成對server的調(diào)用。
ServiceManager
既然這里提到了server,那么我們有必要先了解下在android中是怎么來管理server的。先來看一個(gè)重要的Native進(jìn)程:ServiceManager,從名字可以看出來,這個(gè)是用來管理所有server的。在init進(jìn)程啟動之后,會啟動另外兩個(gè)重要的進(jìn)程,一個(gè)是我們上一篇講的Zygote進(jìn)程,另外一個(gè)就是這個(gè)ServiceManager進(jìn)程了,這兩個(gè)進(jìn)程啟動之后就建立了android的運(yùn)行環(huán)境和server的管理環(huán)境。ServiceManager進(jìn)程啟動之后其他server就可以通過ServiceManager的add_service和check_service來添加和獲取特定的server了。關(guān)于ServiceManager在接下來會詳細(xì)介紹,因?yàn)锽inder會涉及到ServiceManager,所以先簡單介紹下,有個(gè)大概印象,知道他是干什么的就行了。
Binder與進(jìn)程間通信
在本篇介紹中,我們所指的客戶端沒有特別說明的話就指應(yīng)用程序。應(yīng)為service和serviceManager通信也會涉及到IPC。
我們還是從activity的啟動開始來研究Binder的機(jī)制。來看下startActivity涉及通信的類圖:
在ActivityManagerProxy中,有這句代碼
- IBinder b = ServiceManager.getService("activity");
- 繼續(xù)看下getService方法,在getService中對數(shù)據(jù)進(jìn)行了序列化封裝,并通過BinderProxy的native方法向ServiceManager發(fā)送請求,獲取Binder的代理對象??聪耮etService代碼:
- /*
- * 從ServiceManager中獲取service對應(yīng)的代理Binder
- * @param na
- * @return
- * @throws RemoteException
- */
- 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);
- IBinder binder = reply.readStrongBinder();
- reply.recycle();
- data.recycle();
- return binder;
- }
也就是說,在android中進(jìn)行IPC的話,需要先通過ServiceManager獲得客戶端的代理,然后再通過該代理與對應(yīng)的service進(jìn)行通信。
- 建立和ServiceManager的連接,獲取客戶端對象的代理Binder。
- 客戶端再通過該代理binder和服務(wù)器端進(jìn)行通信。
真正的Binder
我們在上面所提到的這些Binder實(shí)際上只是JVM中的Binder,主要作用是提供了訪問C++中的代理Binder,叫做BpBinder(BproxyBinder)。真正的Binder是Linux上的一個(gè)驅(qū)動設(shè)備,專門用來做android的數(shù)據(jù)交換。
從上面分析可以看出,一次IPC通信大概有以下三個(gè)步驟:
- 在JVM中對數(shù)據(jù)進(jìn)行序列化,并通過BinderProxy傳遞到C++中。
- C++中的BpBinder對數(shù)據(jù)進(jìn)行處理,并傳入到Binder設(shè)備中(這里是在ProcessState類中處理并調(diào)用BpBinder).
- Service從內(nèi)核設(shè)備中讀取數(shù)據(jù)。
既然在C++中,處理數(shù)據(jù)主要是在ProcessState中,那么我們就來看看ProcessState的代碼,在getContextObject中調(diào)用了getStrongProxyForHandle方法,從而獲取了代理對象BpBinder:
- sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
- {
- sp<IBinder> result;
- AutoMutex _l(mLock);
- handle_entry* e = lookupHandleLocked(handle);
- if (e != NULL) {
- // We need to create a new BpBinder if there isn't currently one, OR we
- // are unable to acquire a weak reference on this current one. See comment
- // in getWeakProxyForHandle() for more info about this.
- IBinder* b = e->binder;
- if (b == NULL || !e->refs->attemptIncWeak(this)) {
- b = new BpBinder(handle);
- e->binder = b;
- if (b) e->refs = b->getWeakRefs();
- result = b;
- } else {
- // This little bit of nastyness is to allow us to add a primary
- // reference to the remote proxy when this team doesn't have one
- // but another team is sending the handle to us.
- result.force_set(b);
- e->refs->decWeak(this);
- }
- }
- return result;
- }
再來看看BpBinder中的transact方法代碼:
- status_t BpBinder::transact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
- {
- // Once a binder has died, it will never come back to life.
- if (mAlive) {
- status_t status = IPCThreadState::self()->transact(
- mHandle, code, data, reply, flags);
- if (status == DEAD_OBJECT) mAlive = 0;
- return status;
- }
- return DEAD_OBJECT;
- }
在BpBinder中的transact函數(shù)中,只是調(diào)用了IPCThreadState::self()->transact方法,也就是說,數(shù)據(jù)處理是在IPCThreadState類中的transact。在transact中,它把請求的數(shù)據(jù)經(jīng)過Binder設(shè)備發(fā)送給了Service。Service處理完請求后,又將結(jié)果原路返回給客戶端。
總結(jié):
- 在android中,使用Binder進(jìn)行進(jìn)程間的通信,并采用C/S架構(gòu)
- Android中的Binder分為JVM中的、C++中的、和真正的linux中的Binder塊設(shè)備
- 進(jìn)程間通信首先是從JVM中對數(shù)據(jù)進(jìn)行轉(zhuǎn)化并傳遞到C++中,C++中的BpBinder對數(shù)據(jù)進(jìn)行處理寫入到linux中的Binder設(shè)備,并接受Service端得請求,請求完畢后按照原路返回給調(diào)用端。
|