Android處理序間通訊-AIDL實現原理

來源:互聯網
上載者:User

標籤:理解   例子   擷取   服務   檔案   組成   blog   不同   任務   

Android處理序間通訊基於Proxy(代理)與Stub(樁或存根)的設計模式(1-1所示)。其中,Proxy將特殊性介面轉換成通用性介面,Stub將通用性介面轉換成特殊性介面,二者之間的資料轉換通過Parcel(打包)進行的,Proxy常作為資料發送代理,通過Parcel將資料打包發送,Stub常作為資料接收樁,解包並解析Parcel Data package。Android處理序間通訊就是通過這樣的 “代理-樁” 的設計模式運作的。

                                                           圖 1-1

關於Proxy與Stub注意:

  1. Stub 跟 Proxy 是一對,俗稱“代理-樁”,一般用在遠程方法調用。
  2. Proxy 相當於是拿在手裡的遙控器,而 Stub 相當於長在電視機裡的遙控接收器,它們有著一一對應的介面方法,但操作的方向剛好相反。
  3. Proxy 的介面供用戶端程式調用,然後它內部會把資訊封裝好,以某種方式(比如 RMI)傳遞給 Stub,而後者通過對應的介面作用於服務端系統,從而完成了“遠程調用”。
  4. 一般不同處理序間通訊的時候都會用到這種模式。
  5. 關於Stub的asInterface(Binder), 可以返回Stub或Stub.Proxy(如果用戶端和服務端在同一個進程下,那麼asInterface()將返回Stub對象本身,否則返回Stub.Proxy對象)。我們都知道,Binder的工作機制用戶端,Binder,服務端組成的,用戶端和服務端都是通過Binder來交流的(Binder也是Android中一個java類)。AIDL產生的java代碼中,Stub類是繼承於Binder類的,也就是說Stub執行個體就是Binder執行個體。
  6. Stub和Stub.Proxy的區別:(1)如果在同一個進程下的話,那麼asInterface()將返回服務端的Stub對象本身,因為此時根本不需要跨進稱通訊,那麼直接調用Stub對象的介面就可以了,返回的實現就是服務端的Stub實現,也就是根本沒有跨進程通訊;(2)如果不是同一個進程,那麼asInterface()返回是Stub.Proxy對象,該對象持有著遠端Binder引用,因為現在需要跨進程通訊,所以如果調用Stub.Proxy的介面的話,那麼它們都將是IPC調用,它會通過調用transact方法去與服務端通訊。

關於AIDL定義以及實現流程圖:

AIDL是一個縮寫,全稱是Android Interface Definition Language,也就是Android介面定義語言。我們在寫完AIDL檔案後,編譯器會幫我們自動產生一個同名的 .java 檔案(在gen相應目錄下)。在服務端和用戶端中也可以照常使用這個 .java 類來進行跨進程通訊。

關於Proxy類幾個對象及方法(用戶端最終通過這個Proxy類與服務端進行通訊)

    • 關於 _data_reply 對象:一般來說,我們會將方法的傳參的資料存入_data 中,而將方法的傳回值的資料存入 _reply 中—在沒涉及定向 tag 的情況下。如果涉及了定向 tag ,情況將會變得稍微複雜些,具體是怎麼回事請參見這篇博文:你真的理解AIDL中的in,out,inout嗎?
    • 關於 Parcel :簡單的來說,Parcel 是一個用來存放和讀取資料的容器。我們可以用它來進行用戶端和服務端之間的資料轉送,當然,它能傳輸的只能是可序列化的資料。具體 Parcel 的使用方法和相關原理可以參見這篇文章:Android中Parcel的分析以及使用
    • 關於 transact() 方法:這是用戶端和服務端通訊的核心方法。調用這個方法之後,用戶端將會掛起當前線程,等候服務端執行完相關任務後通知並接收返回的 _reply 資料流。關於這個方法的傳參,這裡有兩點需要說明的地方: 
      • 方法 ID :transact() 方法的第一個參數是一個方法 ID ,這個是用戶端與服務端約定好的給方法的編碼,彼此一一對應。在AIDL檔案轉化為 .java 檔案的時候,系統將會自動給AIDL檔案裡面的每一個方法自動分配一個方法 ID。
      • 第四個參數:transact() 方法的第四個參數是一個 int 值,它的作用是設定進行 IPC 的模式,為 0 表示資料可以雙向流通,即 _reply 流可以正常的攜帶資料回來,如果為 1 的話那麼資料將只能單向流通,從服務端回來的 _reply 流將不攜帶任何資料。 
        註:AIDL產生的 .java 檔案的這個參數均為 0。

關於用戶端一般的工作流程:

  • 1,產生 _data 和 _reply 資料流,並向 _data 中存入用戶端的資料。
  • 2,通過 transact() 方法將它們傳遞給服務端,並請求服務端調用指定方法。
  • 3,接收 _reply 資料流,並從中取出服務端傳回來的資料。

關於服務端的一般工作流程:

  • 1,擷取用戶端傳過來的資料,根據方法 ID 執行相應操作。
  • 2,將傳過來的資料取出來,調用本地寫好的對應方法。
  • 3,將需要回傳的資料寫入 reply 流,傳回用戶端。

關於Android中AIDL的簡單例子,參加如下Demo:

53400288

(注意:在Android Studio中,用戶端和服務端的AIDL介面檔案所在的包未必相同,最好在gradle中配置路徑!)

 

其它參考連結:

49970217 

51173668

52029091 (詳細原理來分析,good)

 

Android處理序間通訊-AIDL實現原理

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.