前面幾篇文章中已經介紹了進程間的通訊,你們應該對aidl很熟悉了,可是對aidl具體不是很熟悉,這篇文章中將帶領你們一塊兒來學習下aidl的詳細語法。web
什麼是aidl?編程
AIDL(Android 接口定義語言)與您可能使用過的其餘 IDL 相似。 您能夠利用它定義客戶端與服務使用進程間通訊 (IPC) 進行相互通訊時都承認的編程接口。 在 Android 上,一個進程一般沒法訪問另外一個進程的內存。 儘管如此,進程須要將其對象分解成操做系統可以識別的原語,並將對象編組成跨越邊界的對象。 編寫執行這一編組操做的代碼是一項繁瑣的工做,所以 Android 會使用 AIDL 來處理。安全
在您開始設計 AIDL 接口以前,要注意 AIDL 接口的調用是直接函數調用。 您不該該假設發生調用的線程。 視調用來自本地進程仍是遠程進程中的線程,實際狀況會有所差別。 具體而言:併發
- 來自本地進程的調用在發起調用的同一線程內執行。若是該線程是您的主 UI 線程,則該線程繼續在 AIDL 接口中執行。 若是該線程是其餘線程,則其即是在服務中執行您的代碼的線程。 所以,只有在本地線程訪問服務時,您才能徹底控制哪些線程在服務中執行(但若是真是這種狀況,您根本不該該使用 AIDL,而是應該經過實現 Binder 類建立接口)。
- 來自遠程進程的調用分派自平臺在您的自有進程內部維護的線程池。 您必須爲來自未知線程的屢次併發傳入調用作好準備。 換言之,AIDL 接口的實現必須是徹底線程安全實現。
- oneway 關鍵字用於修改遠程調用的行爲。使用該關鍵字時,遠程調用不會阻塞;它只是發送事務數據並當即返回。接口的實現最終接收此調用時,是以正常遠程調用形式將其做爲來自 Binder 線程池的常規調用進行接收。 若是 oneway 用於本地調用,則不會有任何影響,調用還是同步調用。
您必須使用 Java 編程語言語法在 .aidl 文件中定義 AIDL 接口,而後將它保存在託管服務的應用以及任何其餘綁定到服務的應用的源代碼(src/ 目錄)內。編程語言
您開發每一個包含 .aidl 文件的應用時,Android SDK 工具都會生成一個基於該 .aidl 文件的 IBinder 接口,並將其保存在項目的 gen/ 目錄中。服務必須視狀況實現 IBinder 接口。而後客戶端應用即可綁定到該服務,並調用 IBinder 中的方法來執行 IPC。svg
如需使用 AIDL 建立綁定服務,請執行如下步驟:函數
- 建立 .aidl 文件
此文件定義帶有方法簽名的編程接口。
- 實現接口
Android SDK 工具基於您的 .aidl 文件,使用 Java 編程語言生成一個接口。此接口具備一個名爲 Stub 的內部抽象類,用於擴展 Binder 類並實現 AIDL 接口中的方法。您必須擴展 Stub 類並實現方法。
- 向客戶端公開該接口
實現 Service 並重寫 onBind() 以返回 Stub 類的實現。
AIDL 使用簡單語法,使您能經過可帶參數和返回值的一個或多個方法來聲明接口。 參數和返回值能夠是任意類型,甚至能夠是其餘 AIDL 生成的接口。工具
您必須使用 Java 編程語言構建 .aidl 文件。每一個 .aidl 文件都必須定義單個接口,而且只需包含接口聲明和方法簽名。學習
默認狀況下,AIDL 支持下列數據類型:操作系統
- Java 編程語言中的全部原語類型(如 int、long、char、boolean 等等)
- String
- CharSequence
- List
List 中的全部元素都必須是以上列表中支持的數據類型、其餘 AIDL 生成的接口或您聲明的可打包類型。 可選擇將 List 用做「通用」類(例如,List)。另外一端實際接收的具體類始終是 ArrayList,但生成的方法使用的是 List 接口。
- Map
Map 中的全部元素都必須是以上列表中支持的數據類型、其餘 AIDL 生成的接口或您聲明的可打包類型。 另外一端實際接收的具體類始終是 HashMap,但生成的方法使用的是 Map 接口。不支持通用 Map(如 Map<
String,Integer>
形式的 Map)
注意:您必須爲以上未列出的每一個附加類型加入一個 import 語句,即便這些類型是在與您的接口相同的軟件包中定義。
定義服務接口時,請注意:
- 方法可帶零個或多個參數,返回值或空值。
- 全部非原語參數都須要指示數據走向的方向標記。能夠是 in、out 或 inout(見如下示例)。原語默認爲 in,不能是其餘方向。
- .aidl 文件中包括的全部代碼註釋都包含在生成的 IBinder 接口中(import 和 package 語句以前的註釋除外)
- 只支持方法;您不能公開 AIDL 中的靜態字段。