AIDL 語言大致上是以 Java 語言為基礎。檔案會指定介面合約,以及此合約中使用的各種資料型別和常數。
套件
每個 AIDL 檔案開頭都有一個選用套件,對應於各種後端的套件名稱。套件宣告如下所示:
package my.package;
與 Java 類似,AIDL 檔案必須位於符合其套件的資料夾結構中。含有套件 my.package 的檔案必須位於 my/package/ 資料夾中。
類型
在 AIDL 檔案中,有很多地方可以指定型別。 如需 AIDL 語言支援的確切型別清單,請參閱「AIDL 後端型別」。
註解
AIDL 語言的幾個部分支援註解。如需註解清單和適用位置,請參閱 AIDL 註解。
匯入
如要使用其他介面中定義的型別,請先在建構系統中新增依附元件。在 cc_* 和 java_* Soong 模組中,如果 .aidl 檔案直接在 Android 平台建構作業的 srcs 下使用,您可以使用 aidl: { include_dirs: ... } 欄位新增目錄。如要瞭解如何使用 aidl_interface 匯入,請參閱這篇文章。
匯入內容如下所示:
import some.package.Foo; // explicit import
在同一個套件中匯入型別時,可以省略套件。不過,如果省略套件,且在全域命名空間中指定類型 (一般來說,所有類型都應為命名空間),可能會導致不明確的匯入錯誤:
import Foo; // same as my.package.Foo
定義類型
AIDL 檔案通常會定義用做介面的型別。
介面
以下是 AIDL 介面範例:
interface ITeleport {
// Location defined elsewhere
void teleport(Location baz, float speed);
String getName();
// ITeleportCallback defined elsewhere
void methodWithCallback(ITeleportCallback callback);
// ITeleportSession defined elsewhere
ITeleportSession getASubInterface();
}
介面會定義一系列方法的物件。方法可以是 oneway (oneway void doFoo()) 或同步。如果介面定義為 oneway (oneway interface ITeleport {...}),則其中的所有方法都會隱含 oneway。單向方法會以非同步方式分派,且無法傳回結果。從同一執行緒到同一繫結器的單向方法也會依序執行 (但可能在不同執行緒上)。如要瞭解如何設定執行緒,請參閱 AIDL 後端執行緒管理。
繫結器可透過繫結器介面共用許多介面和繫結器物件。AIDL 介面經常在方法呼叫中使用回呼,例如上一個範例中的 ITeleportCallback。您可以在呼叫相同方法或不同方法時,重複使用回呼物件。介面型別的另一個常見用途,是從方法傳回子介面或工作階段物件,例如上一個範例中的 ITeleportSession。這種巢狀結構可讓不同的 API 封裝在 API 或執行階段狀態中。舉例來說,工作階段可能代表特定資源的擁有權。在多次傳遞介面,或將介面傳回其來源的用戶端或伺服器時,介面一律會保留基礎繫結器物件的指標等值。
方法可以有零或多個引數。方法引數可以是 in、out 或 inout。如要瞭解這對引數型別的影響,請參閱 AIDL 後端方向性。
Parcelable
如要瞭解如何建立後端專屬的可封送物件,請參閱「AIDL 後端自訂可封送物件」。
Android 10 以上版本支援直接在 AIDL 中定義可封送物件。這類可封送物件稱為結構化可封送物件。如要進一步瞭解結構化和穩定 AIDL 在 AIDL 編譯器和建構系統中的關聯,請參閱「結構化與穩定 AIDL」。
例如:
package my.package;
import my.package.Boo;
parcelable Baz {
@utf8InCpp String name = "baz";
Boo boo;
}
聯集
Android 12 以上版本支援標記聯集宣告。例如:
package my.package;
import my.package.FooSettings;
import my.package.BarSettings;
union Settings {
FooSettings fooSettings;
BarSettings barSettings;
@utf8InCpp String str;
int number;
}
如需後端專屬詳細資料,請參閱 AIDL 後端聯集。
列舉
Android 11 以上版本支援列舉聲明。例如:
package my.package;
enum Boo {
A = 1 * 4,
B = 3,
}
巢狀型別宣告
Android 13 以上版本支援巢狀型別宣告。例如:
package my.package;
import my.package.Baz;
interface IFoo {
void doFoo(Baz.Nested nested); // defined in my/package/Baz.aidl
void doBar(Bar bar); // defined below
parcelable Bar { ... } // nested type definition
}
常數
自訂 AIDL 介面、可封送物件和聯集也可以包含整數和字串常數,例如:
const @utf8InCpp String HAPPY = ":)";
const String SAD = ":(";
const byte BYTE_ME = 1;
const int ANSWER = 6 * 7;
常數運算式
您可以使用常數運算式指定 AIDL 常數、陣列大小和列舉值。運算式可以使用括號巢狀運算。常數運算式值可搭配整數或浮點值使用。
true 和 false 常值代表布林值。如果值含有 . 但沒有後置字串,例如 3.8,系統會視為雙精度值。浮點值會加上 f 後置字串,例如 2.4f。帶有 l 或 L 後置字串的整數值表示 64 位元的長值。否則,整數值會取得 8 位元 (位元組)、32 位元 (int) 和 64 位元 (long) 之間,最小的值保留帶正負號型別。因此 256 會視為 int,但 255 + 1 會溢位為 byte 0。系統會先將十六進位值 (例如 0x3) 解讀為 32 位元和 64 位元之間最小的值保留不帶正負號型別,然後重新解讀為不帶正負號的值。因此,0xffffffff 的值為 int-1。從 Android 13 開始,常數 (例如 3u8) 可以加上 u8 後置字元,代表 byte 值。這個後置字元很重要,因為 0xffu8 * 3 等計算會解譯為 -3,且類型為 byte,而 0xff * 3 則為 765,且類型為 int。
支援的運算子具有 C++ 和 Java 語意。二元運算子的優先順序由低到高依序為 || && | ^ & == != < > <= >= << >> + - * / %。Unary 運算子為 + - ! ~。