AIDL 語言大致上以 Java 語言為基礎。這類檔案會指定介面合約,以及這份合約中使用的各種資料類型和常數。
套件
每個 AIDL 檔案都會以選用的套件開頭,該套件會對應至各種後端中的套件名稱。套件宣告如下所示:
package my.package;
與 Java 類似,AIDL 檔案必須位於與其套件相符的資料夾結構中。套件為 my.package
的檔案必須位於 my/package/
資料夾中。
類型
在 AIDL 檔案中,可以指定類型的位置很多。如需 AIDL 語言支援的類型完整清單,請參閱「AIDL 後端類型」。
註解
AIDL 語言的幾個部分支援註解。如需註解清單和適用位置,請參閱 AIDL 註解。
匯入
如要使用其他介面中定義的類型,您必須先在建構系統中新增依附元件。在 cc_*
和 java_*
Soong 模組中,在 Android 平台建構的 srcs
下,直接使用 .aidl
檔案,您可以使用 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
。Oneway 方法會以非同步方式調度,且無法傳回結果。從相同執行緒到相同繫結器的單向方法也會依序執行 (儘管可能在不同執行緒上)。有關如何設定執行緒的討論,請參閱「AIDL 後端執行緒管理」。
Binder 可讓許多介面和繫結器物件透過繫結器介面共用。AIDL 介面經常會在方法呼叫中使用回呼,例如前述範例中的 ITeleportCallback
。您可以在呼叫相同方法或不同方法之間重複使用回呼物件。介面類型的另一個常見用途是針對子介面或工作階段物件,從方法中傳回,例如上一個範例中包含 ITeleportSession
的方法。這種巢狀結構可讓您在 API 或根據執行階段狀態封裝不同的 API。舉例來說,工作階段可能代表特定資源的擁有權。當介面傳遞多次或傳回原始用戶端或伺服器時,它們一律會保留基礎繫結器物件的指標相等性。
方法可以有零個或多個引數。方法的引數可以是 in
、out
或 inout
。如要瞭解這對引數類型的影響,請參閱 AIDL 後端方向。
Parcelable
如需有關如何建立後端專屬 parcelable 的說明,請參閱 AIDL 後端自訂 parcelable。
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 位元 (長) 之間的最小值保護正負號類型。因此,256
會被視為 int
,但 255 + 1
會溢出為 byte
0
。十六進位值 (例如 0x3
) 會先解讀為 32 位元和 64 位元之間的最小值保留類型,然後再解譯為無正負號值。因此,0xffffffff
具有 int
值 -1
。從 Android 13 開始,您可以將後置字串 u8
新增至常數 (例如 3u8
),用於代表 byte
值。這個字尾很重要,因為它可將計算結果 (例如 0xffu8 * 3
) 解讀為類型為 byte
的 -3
,而 0xff * 3
則是類型為 int
的 765
。
支援的運算子具有 C++ 和 Java 語義。從最低到最高的優先順序,二進位運算子為 || && | ^ & == != < > <= >= << >> + - * / %
。一元運算子為 + - ! ~
。