一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

Android 之 Binder與進(jìn)程間通信

 老匹夫 2013-12-25
分類: Android 2011-07-04 17:43 4358人閱讀 評論(4) 收藏 舉報(bào)

    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中,有這句代碼          

    1. IBinder b = ServiceManager.getService("activity");  
    2. 繼續(xù)看下getService方法,在getService中對數(shù)據(jù)進(jìn)行了序列化封裝,并通過BinderProxy的native方法向ServiceManager發(fā)送請求,獲取Binder的代理對象??聪耮etService代碼:  

    1. /* 
    2.    * 從ServiceManager中獲取service對應(yīng)的代理Binder 
    3.    * @param na 
    4.    * @return 
    5.    * @throws RemoteException 
    6.    */  
    7.   public IBinder getService(String name) throws RemoteException {  
    8.       Parcel data = Parcel.obtain();  
    9.       Parcel reply = Parcel.obtain();  
    10.       data.writeInterfaceToken(IServiceManager.descriptor);  
    11.       data.writeString(name);  
    12.       mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);  
    13.       IBinder binder = reply.readStrongBinder();  
    14.       reply.recycle();  
    15.       data.recycle();  
    16.       return binder;  
    17.   }  

    也就是說,在android中進(jìn)行IPC的話,需要先通過ServiceManager獲得客戶端的代理,然后再通過該代理與對應(yīng)的service進(jìn)行通信。

    1. 建立和ServiceManager的連接,獲取客戶端對象的代理Binder。
    2. 客戶端再通過該代理binder和服務(wù)器端進(jìn)行通信。

    真正的Binder

    我們在上面所提到的這些Binder實(shí)際上只是JVM中的Binder,主要作用是提供了訪問C++中的代理Binder,叫做BpBinder(BproxyBinder)。真正的Binder是Linux上的一個(gè)驅(qū)動設(shè)備,專門用來做android的數(shù)據(jù)交換。

     

    從上面分析可以看出,一次IPC通信大概有以下三個(gè)步驟:

  1. 在JVM中對數(shù)據(jù)進(jìn)行序列化,并通過BinderProxy傳遞到C++中。
  2. C++中的BpBinder對數(shù)據(jù)進(jìn)行處理,并傳入到Binder設(shè)備中(這里是在ProcessState類中處理并調(diào)用BpBinder).
  3. Service從內(nèi)核設(shè)備中讀取數(shù)據(jù)。

   既然在C++中,處理數(shù)據(jù)主要是在ProcessState中,那么我們就來看看ProcessState的代碼,在getContextObject中調(diào)用了getStrongProxyForHandle方法,從而獲取了代理對象BpBinder:

    1. sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)  
    2. {  
    3.     sp<IBinder> result;  
    4.     AutoMutex _l(mLock);  
    5.     handle_entry* e = lookupHandleLocked(handle);  
    6.     if (e != NULL) {  
    7.         // We need to create a new BpBinder if there isn't currently one, OR we   
    8.         // are unable to acquire a weak reference on this current one.  See comment   
    9.         // in getWeakProxyForHandle() for more info about this.   
    10.         IBinder* b = e->binder;  
    11.         if (b == NULL || !e->refs->attemptIncWeak(this)) {  
    12.             b = new BpBinder(handle);  
    13.             e->binder = b;  
    14.             if (b) e->refs = b->getWeakRefs();  
    15.             result = b;  
    16.         } else {  
    17.             // This little bit of nastyness is to allow us to add a primary   
    18.             // reference to the remote proxy when this team doesn't have one   
    19.             // but another team is sending the handle to us.   
    20.             result.force_set(b);  
    21.             e->refs->decWeak(this);  
    22.         }  
    23.     }  
    24.     return result;  
    25. }  

    再來看看BpBinder中的transact方法代碼:

    1. status_t BpBinder::transact(  
    2.     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)  
    3. {  
    4.     // Once a binder has died, it will never come back to life.   
    5.     if (mAlive) {  
    6.         status_t status = IPCThreadState::self()->transact(  
    7.             mHandle, code, data, reply, flags);  
    8.         if (status == DEAD_OBJECT) mAlive = 0;  
    9.         return status;  
    10.     }  
    11.     return DEAD_OBJECT;  
    12. }  
    在BpBinder中的transact函數(shù)中,只是調(diào)用了IPCThreadState::self()->transact方法,也就是說,數(shù)據(jù)處理是在IPCThreadState類中的transact。在transact中,它把請求的數(shù)據(jù)經(jīng)過Binder設(shè)備發(fā)送給了Service。Service處理完請求后,又將結(jié)果原路返回給客戶端。

     

    總結(jié):

  1. 在android中,使用Binder進(jìn)行進(jìn)程間的通信,并采用C/S架構(gòu)
  2. Android中的Binder分為JVM中的、C++中的、和真正的linux中的Binder塊設(shè)備
  3. 進(jìn)程間通信首先是從JVM中對數(shù)據(jù)進(jìn)行轉(zhuǎn)化并傳遞到C++中,C++中的BpBinder對數(shù)據(jù)進(jìn)行處理寫入到linux中的Binder設(shè)備,并接受Service端得請求,請求完畢后按照原路返回給調(diào)用端。

    本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    欧美人妻少妇精品久久性色| 国产欧美性成人精品午夜| 精品国产av一区二区三区不卡蜜| 精品国产成人av一区二区三区| 能在线看的视频你懂的| 嫩呦国产一区二区三区av| 乱女午夜精品一区二区三区 | 日本最新不卡免费一区二区| 麻豆亚州无矿码专区视频| 91欧美一区二区三区成人| 一区二区不卡免费观看免费| 欧美日韩国产精品第五页| 日本最新不卡免费一区二区| 中文字幕日产乱码一区二区| 激情内射亚洲一区二区三区| 国产国产精品精品在线| 欧美日本亚欧在线观看| 国产欧美日韩精品一区二区| 国产传媒精品视频一区| 99视频精品免费视频| 91插插插外国一区二区婷婷| 精品国自产拍天天青青草原| 日韩精品一区二区三区射精| 国产毛片不卡视频在线| 久久经典一区二区三区| 天堂av一区一区一区| 中文人妻精品一区二区三区四区| 欧美亚洲综合另类色妞| 日本美国三级黄色aa| 亚洲最新中文字幕在线视频| 国产精品日韩精品一区| 欧美夫妻性生活一区二区| 日韩精品一区二区不卡| 亚洲高清亚洲欧美一区二区| 免费观看一区二区三区黄片| 亚洲男人的天堂久久a| 国产欧美亚洲精品自拍| 国产麻豆一线二线三线| 亚洲欧美日本国产不卡| 亚洲综合一区二区三区在线| 日本午夜免费啪视频在线|