AIDL 語言

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。Oneway 方法會以非同步方式調度,且無法傳回結果。從同一個執行緒傳送至同一個 Binder 的單向方法也會依序執行 (但可能會在不同執行緒上執行)。如要瞭解如何設定執行緒,請參閱「AIDL 後端執行緒管理」。

Binder 可讓許多介面和繫結器物件透過繫結器介面共用。AIDL 介面經常會在方法呼叫中使用回呼,例如前述範例中的 ITeleportCallback。您可以在呼叫相同方法或不同方法之間重複使用回呼物件。介面類型的另一個常見用途,是用於從方法傳回子介面或工作階段物件,例如上一個範例中的 ITeleportSession。這種巢狀結構可讓您在 API 或根據執行階段狀態封裝不同的 API。舉例來說,工作階段可能代表 特定資源的擁有權當介面傳遞多次或傳回原始用戶端或伺服器時,它們一律會保留基礎繫結器物件的指標相等性。

方法可以有零個或多個引數。方法的引數可以是 inoutinout。有關這對引數類型的影響, 看 AIDL 後端方向

Parcelable

如需有關如何建立後端專屬 parcelable 的說明, AIDL 後端 parcelables

Android 10 以上版本可直接在 AIDL 中支援可分割定義。這種類型的 parcelable 稱為結構化 parcelable。 如要進一步瞭解結構化和穩定的 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;
    }

列舉

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 常數、陣列大小和列舉值 運算式。運算式可以使用括號巢狀排列運算。常數運算式值可搭配整數或浮點值使用。

truefalse 常值代表布林值。含有 . 但沒有後置字串的值 (例如 3.8) 會視為雙精度值。浮點值 值的後置字串為 f,例如 2.4f。含有 lL 後置字串的整數值,表示 64 位元長的值。否則,積分值會 介於 8 位元 (位元組)、32 位元 (int) 之間的最小含值正負號類型, 和 64 位元 (長)。因此,256 會視為 int,但 255 + 1 溢位為 byte 0。系統會先解譯 0x3 這類十六進位值 做為 32 位元和 64 位元之間的最小值保留類型 然後重新解讀為無正負號值因此,0xffffffffint 值是 -1。從 Android 13 開始,後置字串 u8 可以是 加到常數 (例如 3u8) 以表示 byte 值。這個字尾很重要,因為計算作業 (例如 0xffu8 * 3) 會解讀為類型為 byte-3,而 0xff * 3 則是類型為 int765

支援的運算子具有 C++ 和 Java 語義。從最低到最高的優先順序,二進位運算子為 || && | ^ & == != < > <= >= << >> + - * / %。一元運算子為 + - ! ~