• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            life02

              C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
              197 隨筆 :: 3 文章 :: 37 評(píng)論 :: 0 Trackbacks
             

            發(fā)布于2011-09-28

             

            Android 核心分析 之六 -----IPC框架分析 Binder,Service,Service manager

            我首先從宏觀的角度觀察Binder,Service,Service Manager,并闡述各自的概念。從Linux的概念空間中,Android的設(shè)計(jì)Activity托管在不同的的進(jìn)程,Service也都是托管在不同的進(jìn)程,不同進(jìn)程間的Activity,Service之間要交換數(shù)據(jù)屬于IPC。Binder就是為了Activity通訊而設(shè)計(jì)的一個(gè)輕量級(jí)的IPC框架。

            在代碼分析中,我發(fā)現(xiàn)Android中只是把Binder理解成進(jìn)程間通訊的實(shí)現(xiàn),有點(diǎn)狹隘,而是應(yīng)該站在公共對(duì)象請(qǐng)求代理這個(gè)高度來理解Binder,Service的概念,這樣我們就會(huì)看到不一樣的格局,從這個(gè)高度來理解設(shè)計(jì)意圖,我們才會(huì)對(duì)Android中的一些天才想法感到驚奇。從Android的外特性概念空間中,我們看不到進(jìn)程的概念,而是Activity,Service,AIDL,INTENT。一般的如果我作為設(shè)計(jì)者,在我們的根深蒂固的想法中,這些都是如下的C/S架構(gòu),客戶端和服務(wù)端直接通過Binder交互數(shù)據(jù),打開Binder寫入數(shù)據(jù),通過Binder讀取數(shù)據(jù),通訊就可以完成了。

            該注意到Android的概念中,Binder是一個(gè)很低層的概念,上面一層根本都看不到Binder,而是Activity跟一個(gè)Service的對(duì)象直接通過方法調(diào)用,獲取服務(wù)。

            這個(gè)就是Android提供給我們的外特性:在Android中,要完成某個(gè)操作,所需要做的就是請(qǐng)求某個(gè)有能力的服務(wù)對(duì)象去完成動(dòng)作,而無需知道這個(gè)通訊是怎樣工作的,以及服務(wù)在哪里。所以Andoid的IPC在本質(zhì)上屬于對(duì)象請(qǐng)求代理架構(gòu),Android的設(shè)計(jì)者用CORBA的概念將自己包裝了一下,實(shí)現(xiàn)了一個(gè)微型的輕量級(jí)CORBA架構(gòu),這就是Andoid的IPC設(shè)計(jì)的意圖所在,它并不是僅僅解決通訊,而是給出了一個(gè)架構(gòu),一種設(shè)計(jì)理念,這就是Android的閃光的地方。Android的Binder更多考慮了數(shù)據(jù)交換的便捷,并且只是解決本機(jī)的進(jìn)程間的通訊,所以不像CORBA那樣復(fù)雜,所以叫做輕量級(jí)。

            所以要理解Android的IPC架構(gòu),就需要了解CORBA的架構(gòu)。而CORBA的架構(gòu)在本質(zhì)上可以使用下面圖來表示:

            在服務(wù)端,多了一個(gè)代理器,更為抽象一點(diǎn)我們可以下圖來表示。

            分析和CORBA的大體理論架構(gòu),我給出下面的Android的對(duì)象代理結(jié)構(gòu)。

            在結(jié)構(gòu)圖中,我們可以較為清楚的把握Android的IPC包含了如下的概念:

            設(shè)備上下文什(ContextObject)

            設(shè)備上下文包含關(guān)于客服端,環(huán)境或者請(qǐng)求中沒有作為參數(shù)傳遞個(gè)操作的上下文信息,應(yīng)用程序開發(fā)者用ContextObject接口上定義的操作來創(chuàng)建和操作上下文。

            Android代理:這個(gè)是指代理對(duì)象

            Binder Linux內(nèi)核提供的Binder通訊機(jī)制

            Android的外特性空間是不需要知道服務(wù)在那里,只要通過代理對(duì)象完成請(qǐng)求,但是我們要探究Android是如何實(shí)現(xiàn)這個(gè)架構(gòu),首先要問的是在Client端要完成云服務(wù)端的通訊,首先應(yīng)該知道服務(wù)在哪里?我們首先來看看Service Manger管理了那些數(shù)據(jù)。Service Manager提供了add service,check service兩個(gè)重要的方法,并且維護(hù)了一個(gè)服務(wù)列表記錄登記的服務(wù)名稱和句柄。

            Service manager service使用0來標(biāo)識(shí)自己。并且在初始化的時(shí)候,通過binder設(shè)備使用BINDER_SET_CONTEXT_MGR ioctl將自己變成了CONTEXT_MGR。Svclist中存儲(chǔ)了服務(wù)的名字和Handle,這個(gè)Handle作為Client端發(fā)起請(qǐng)求時(shí)的目標(biāo)地址。服務(wù)通過add_service方法將自己的名字和Binder標(biāo)識(shí)handle登記在svclist中。而服務(wù)請(qǐng)求者,通過check_service方法,通過服務(wù)名字在service list中獲取到service 相關(guān)聯(lián)的Binder的標(biāo)識(shí)handle,通過這個(gè)Handle作為請(qǐng)求包的目標(biāo)地址發(fā)起請(qǐng)求。

            我們理解了Service Manager的工作就是登記功能,現(xiàn)在再回到IPC上,客服端如何建立連接的?我們首先回到通訊的本質(zhì):IPC。從一般的概念來講,Android設(shè)計(jì)者在Linux內(nèi)核中設(shè)計(jì)了一個(gè)叫做Binder的設(shè)備文件,專門用來進(jìn)行Android的數(shù)據(jù)交換。所有從數(shù)據(jù)流來看Java對(duì)象從Java的VM空間進(jìn)入到C++空間進(jìn)行了一次轉(zhuǎn)換,并利用C++空間的函數(shù)將轉(zhuǎn)換過的對(duì)象通過driver/binder設(shè)備傳遞到服務(wù)進(jìn)程,從而完成進(jìn)程間的IPC。這個(gè)過程可以用下圖來表示。

            這里數(shù)據(jù)流有幾層轉(zhuǎn)換過程。

            (1) 從JVM空間傳到c++空間,這個(gè)是靠JNI使用ENV來完成對(duì)象的映射過程。

            (2) 從c++空間傳入內(nèi)核Binder設(shè)備,使用ProcessState類完成工作。

            (3) Service從內(nèi)核中Binder設(shè)備讀取數(shù)據(jù)。

            Android設(shè)計(jì)者需要利用面向?qū)ο蟮募夹g(shù)設(shè)計(jì)一個(gè)框架來屏蔽掉這個(gè)過程。要讓上層概念空間中沒有這些細(xì)節(jié)。Android設(shè)計(jì)者是怎樣做的呢?我們通過c++空間代碼分析,看到有如下空間概念包裝(ProcessState@(ProcessState.cpp)

            在ProcessState類中包含了通訊細(xì)節(jié),利用open_binder打開Linux設(shè)備dev/binder,通過ioctrl建立的基本的通訊框架。利用上層傳遞下來的servicehandle來確定請(qǐng)求發(fā)送到那個(gè)Service。通過分析我終于明白了Bnbinder,BpBinder的命名含義,Bn-代表Native,而Bp代表Proxy。一旦理解到這個(gè)層次,ProcessState就容易弄明白了。

            下面我們看JVM概念空間中對(duì)這些概念的包裝。為了通篇理解設(shè)備上下文,我們需要將Android VM概念空間中的設(shè)備上下文和C++空間總的設(shè)備上下文連接起來進(jìn)行研究。

            為了在上層使用統(tǒng)一的接口,在JVM層面有兩個(gè)東西。在Android中,為了簡(jiǎn)化管理框架,引入了ServiceManger這個(gè)服務(wù)。所有的服務(wù)都是從ServiceManager開始的,只用通過Service Manager獲取到某個(gè)特定的服務(wù)標(biāo)識(shí)構(gòu)建代理IBinder。在Android的設(shè)計(jì)中利用Service Manager是默認(rèn)的Handle為0,只要設(shè)置請(qǐng)求包的目標(biāo)句柄為0,就是發(fā)給Service Manager這個(gè)Service的。在做服務(wù)請(qǐng)求時(shí),Android建立一個(gè)新的Service Manager Proxy。Service Manager Proxy使用ContexObject作為Binder和Service Manager Service(服務(wù)端)進(jìn)行通訊。

            我們看到Android代碼一般的獲取Service建立本地代理的用法如下:

            IXXX mIxxx=IXXXInterface.Stub.asInterface(ServiceManager.getService("xxx"));

            例如:使用輸入法服務(wù):

            IInputMethodManager mImm=

            IInputMethodManager.Stub.asInterface(ServiceManager.getService("input_method"));

            這些服務(wù)代理獲取過程分解如下:

            (1) 通過調(diào)用GetContextObject調(diào)用獲取設(shè)備上下對(duì)象。注意在AndroidJVM概念空間的ContextObject只是 與Service Manger Service通訊的代理Binder有對(duì)應(yīng)關(guān)系。這個(gè)跟c++概念空間的GetContextObject意義是不一樣的。

            注意看看關(guān)鍵的代碼

            BinderInternal.getContextObject() @BinderInteral.java

            NATIVE JNI:getContextObject() @android_util_Binder.cpp

            Android_util_getConextObject @android_util_Binder.cpp

            ProcessState::self()->getCotextObject(0) @processState.cpp

            getStrongProxyForHandle(0) @

            NEW BpBinder(0)

            注意ProcessState::self()->getCotextObject(0) @processtate.cpp,就是該函數(shù)在進(jìn)程空間建立 了ProcessState對(duì)象,打開了Binder設(shè)備dev/binder,并且傳遞了參數(shù)0,這個(gè)0代表了與Service Manager這個(gè)服務(wù)綁定。

            (2) 通過調(diào)用ServiceManager.asInterface(ContextObject)建立一個(gè)代理ServiceManger。

            mRemote= ContextObject(Binder)

            這樣就建立起來ServiceManagerProxy通訊框架。

            (3)客戶端通過調(diào)用ServiceManager的getService的方法建立一個(gè)相關(guān)的代理Binder。

            ServiceMangerProxy.remote.transact(GET_SERVICE)

            IBinder=ret.ReadStrongBinder() -》這個(gè)就是JVM空間的代理Binder

            JNI Navite: android_os_Parcel_readStrongBinder() @android_util_binder.cpp

            Parcel->readStrongBinder() @pacel.cpp

            unflatten_binder @pacel.cpp

            getStrongProxyForHandle(flat_handle)

            NEW BpBinder(flat_handle)-》這個(gè)就是底層c++空間新建的代理Binder。

            整個(gè)建立過程可以使用如下的示意圖來表示:

            Activity為了建立一個(gè)IPC,需要建立兩個(gè)連接:訪問Servicemanager Service的連接,IXXX具體XXX Service的代理對(duì)象與XXXService的連接。這兩個(gè)連接對(duì)應(yīng)c++空間ProcessState中BpBinder。對(duì)IXXX的操作最后就是對(duì)BpBinder的操作。由于我們?cè)趯懸粋€(gè)Service時(shí),在一個(gè)Package中寫了Service Native部分和Service Proxy部分,而Native和Proxy都實(shí)現(xiàn)相同的接口:IXXX Interface,但是一個(gè)在服務(wù)端,一個(gè)在客服端。客戶端調(diào)用的方式是使用remote->transact方法向Service發(fā)出請(qǐng)求,而在服務(wù)端的OnTransact中則是處理這些請(qǐng)求。所以在Android Client空間就看到這個(gè)效果:只需要調(diào)用代理對(duì)象方法就達(dá)到了對(duì)遠(yuǎn)程服務(wù)的調(diào)用目的,實(shí)際上這個(gè)調(diào)用路徑好長(zhǎng)好長(zhǎng)。

            我們其實(shí)還一部分沒有研究,就是同一個(gè)進(jìn)程之間的對(duì)象傳遞與遠(yuǎn)程傳遞是區(qū)別的。同一個(gè)進(jìn)程間專遞服務(wù)地和對(duì)象,就沒有代理BpBinder產(chǎn)生,而只是對(duì)象的直接應(yīng)用了。應(yīng)用程序并不知道數(shù)據(jù)是在同一進(jìn)程間傳遞還是不同進(jìn)程間傳遞,這個(gè)只有內(nèi)核中的Binder知道,所以內(nèi)核Binder驅(qū)動(dòng)可以將Binder對(duì)象數(shù)據(jù)類型從BINDER_TYPE_BINDER修改為BINDER_TYPE_HANDLE或者BINDER_TYPE_WEAK_HANDLE作為引用傳遞。

            posted on 2011-12-08 11:37 life02 閱讀(474) 評(píng)論(0)  編輯 收藏 引用 所屬分類: android組件學(xué)習(xí)
            久久激情五月丁香伊人| 狠狠色综合网站久久久久久久| 久久夜色撩人精品国产| 亚洲国产精品久久久天堂| 久久精品无码一区二区app| 久久久久波多野结衣高潮| 欧美一区二区精品久久| 久久综合亚洲色一区二区三区| 欧美一区二区三区久久综| 开心久久婷婷综合中文字幕| 久久久国产精品亚洲一区| 囯产极品美女高潮无套久久久| 久久久这里有精品| 久久久久国产精品嫩草影院| 久久久久久综合一区中文字幕| 少妇精品久久久一区二区三区| 亚洲国产精品无码久久久久久曰| 久久线看观看精品香蕉国产| 国产99久久精品一区二区| 久久er99热精品一区二区| 国产成年无码久久久久毛片| 久久人人爽人人爽人人AV东京热| 综合网日日天干夜夜久久| 性色欲网站人妻丰满中文久久不卡| 一本久久免费视频| 久久精品国产清高在天天线| 99久久国产综合精品网成人影院 | 亚洲综合熟女久久久30p| 久久亚洲精品中文字幕| 久久青青草原综合伊人| 日韩亚洲国产综合久久久| 久久WWW免费人成一看片| 久久99热精品| 中文字幕无码精品亚洲资源网久久 | 精品久久久久久国产三级| 囯产精品久久久久久久久蜜桃| 久久免费高清视频| 嫩草伊人久久精品少妇AV| 无码任你躁久久久久久老妇| av无码久久久久不卡免费网站| 色婷婷噜噜久久国产精品12p|