<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    小菜毛毛技術(shù)分享

    與大家共同成長

      BlogJava :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
      164 Posts :: 141 Stories :: 94 Comments :: 0 Trackbacks
    http://blog.csdn.net/maxleng/archive/2010/04/15/5490770.aspx

    IPC框架分析 Binder,Service,Service manager


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

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


     

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

     

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

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




     

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

     



     

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




     

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

     

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

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

    •  Android代理:這個是指代理對象
    •  Binder Linux內(nèi)核提供的Binder通訊機制

     

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



     

     

     

     

     

     


     

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

     

     

     

     

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

     

     


     

     


     

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

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

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

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

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



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

     

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

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

     

    我們看到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è)備上下對象。注意在AndroidJVM概念空間的ContextObject只是 Service Manger Service通訊的代理Binder有對應(yīng)關(guān)系。這個跟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ù)在進程空間建立 ProcessState對象,打開了Binder設(shè)備dev\binder,并且傳遞了參數(shù)0,這個0代表了與Service Manager這個服務(wù)綁定。

    (2) 通過調(diào)用ServiceManager.asInterfaceContextObject)建立一個代理ServiceManger

         mRemote= ContextObject(Binder)

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

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

     

                  ServiceMangerProxy.remote.transact(GET_SERVICE)

                       IBinder=ret.ReadStrongBinder() -》這個就是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)-》這個就是底層c++空間新建的代理Binder。

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

     

     




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

     

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

    posted on 2010-11-21 21:13 小菜毛毛 閱讀(961) 評論(0)  編輯  收藏 所屬分類: andriod
    主站蜘蛛池模板: 免费精品久久天干天干| 亚洲一区二区三区播放在线| 亚洲AV色欲色欲WWW| 国产精品久久久久免费a∨| 亚洲黄色网址大全| 美女内射毛片在线看免费人动物| 亚洲AV无码日韩AV无码导航| 成全高清在线观看免费| 亚洲国产精品无码成人片久久| 国产99视频精品免费视频76| 久久久久亚洲AV无码专区桃色 | 亚洲综合激情视频| 曰批视频免费40分钟试看天天| 亚洲黄色在线网站| 青苹果乐园免费高清在线| 亚洲乱妇熟女爽到高潮的片 | 亚洲色婷婷综合开心网| 国产成人va亚洲电影| 国产人成免费视频| 亚洲Aⅴ在线无码播放毛片一线天 亚洲avav天堂av在线网毛片 | 亚洲理论精品午夜电影| 未满十八18禁止免费无码网站| 亚洲国产精品无码专区| 日本免费一区二区久久人人澡| 亚洲av伊人久久综合密臀性色| 久久国产精品免费看| 亚洲成av人在线视| 久久成人免费播放网站| 亚洲国产精品久久久久婷婷软件| 日韩精品人妻系列无码专区免费| 久久av无码专区亚洲av桃花岛| 91福利视频免费观看| 亚洲剧场午夜在线观看| 无码中文字幕av免费放| 亚洲精品成a人在线观看☆| 日韩毛片免费在线观看| 日本黄页网址在线看免费不卡| 亚洲午夜日韩高清一区| 免费人成在线观看播放a| 国产jizzjizz免费看jizz| 人人狠狠综合久久亚洲|