1. 程式人生 > >Android每天一個知識點+Demo—跨程序通訊機制AIDL入門

Android每天一個知識點+Demo—跨程序通訊機制AIDL入門

一 Why-為什麼要用AIDL

沙箱理念:在Android中,每個應用(Application)程式都執行在獨立的程序中,無法直接呼叫到其他應用的資源。當一個應用被執行時,一些操作是被限制的,比如訪問記憶體,訪問感測器等等。

好處:這也保證了當其中一個程式出現異常而不會影響另一個應用程式的正常運轉,這樣做可以最大化地保護系統。 android在設計理念上強調元件化,元件之間的依賴性很小

案例:我們往往發一個intent請求,就可以啟動另一個應用的activity;

          可以啟動一個你不知道在哪個程序的service;

          可以註冊傳送一個廣播;

          可以查詢一個contentProvider獲得你想要的資料。

          這其實都需要跨程序通訊的支援。

二 What-AIDL到底是什麼

1 AIDL到底是什麼

問題:在Android平臺,一個程序通常不能訪問另一個程序的記憶體空間為了使其他的應用程式也可以訪問本應用程式提供的服務。

解決:Android系統採用了遠端過程呼叫(Remote Procedure Call,RPC)方式來實現。

          與很多其他的基於RPC的解決方案一樣,Android使用一種介面定義語言(Interface Definition Language,IDL)來公開服務的介面。

          可以將這種可以跨程序訪問的服務稱為AIDL(Android Interface Definition Language)服務。

原理:Android提供了AIDL工具,可以將物件分解成作業系統可以理解的基本單元,並且有序的通過程序邊界,而通過程式碼來實現這個資料傳輸過程是冗長乏味的。

                                                                              

       最底層的是android的ashmen(Anonymous shared memoryy)機制,它負責輔助實現記憶體的分配,以及跨程序所需要的記憶體共享。

      AIDL(android interface definition language)對Binder的使用進行了封裝,可以讓開發者方便的進行方法的遠端呼叫。

      Intent是最高一層的抽象,方便開發者進行常用的跨程序呼叫。

2 Binder到底是什麼

Binder簡介:binder屬於一個驅動,工作在linux層面,執行在核心態,它的操作完成是基於一段記憶體。

Binder組成:Binder架構由服務端,binder驅動,客戶端三個部分構成。其中服務端,客戶端處在使用者空間,而binder驅動處在核心空間。

                                                         

伺服器端:一個Binder伺服器端就是一個Binder類的物件。當建立一個Binder物件後,內部就會開啟一個執行緒,這個執行緒用於接收binder驅動傳送的資訊,收到訊息後,會執行相關的服務程式碼。

Binder驅動:當服務端成功建立一個Binder物件後,Binder驅動也會相應建立一個mRemote物件,該物件的型別也是Binder類。客戶就可以藉助這個mRemote物件來訪問遠端服務。

客戶端:客戶端要想訪問Binder的遠端服務,就必須獲取遠端服務的Binder物件在binder驅動層對應的mRemote引用。當獲取到mRemote物件的引用後,就可以呼叫相應Binder物件的服務了。

2 Binder相關總結

Binder總結:我們可以看到,客戶端是通過Binder驅動來呼叫服務端的相關服務。

                      首先,在服務端建立一個Binder物件,然後相應在Binder驅動中建立一個Binder物件。

                      接著,客戶端通過獲取Binder驅動中Binder物件的引用來呼叫服務端的服務。

                     在Binder機制中正是藉著Binder驅動將不同程序間的元件bind(粘連)在一起,實現通訊。

                     對Binder而言,Binder可以看成Server提供的實現某個特定服務的訪問接入點, Client通過這個‘地址’向Server傳送請求來使用該服務; 對Client而言,Binder可以看成是通向Server的管道入口,要想和某個Server通訊首先必須建立這個管道並獲得管道入口。

使用效果:我們看不到binder,我們感覺就像是客戶端直接請求服務端請求,然後通過服務端的一個代理物件處理相關工作。Activity與service之間彷彿是一種很直接的,自然的通訊。

三 How-AIDL如何實現

我們以WiFi中WifiManager為例

Settings主要類:

                      

使用AIDL流程:

1.根據IWifiManager介面所建立的Binder伺服器端和客戶端,伺服器端是WifiService,客戶端是WifiManager。

         2. IWifiManager.aidl

         3. IWifiManager.aidl編譯後生成IWifiManager.java,並生成IWifiManager.Stub(伺服器端抽象層)和IWifiManager.Stub.Proxy(客戶端代理實現類)。

        4. WifiService通過繼承IWifiManager.Stub實現;而客戶端通過getService函式獲取IWifiManager.Stub.Proxy,即Service的代理類,將其作為引數傳遞給WifiManager,供其與WifiService通訊時使用。

         5. WifiManager是WiFi部分與外界關聯的介面,使用者通過它來訪問WiFi的核心功能。WifiService是伺服器端的實現,作為WiFi部分的核心,處理實際的驅動載入、掃描、連線、斷開等命令,以及底層上報的事件。