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 {
        void teleport(Location baz, float speed);
        String getName();
    }

インターフェースは、一連のメソッドでオブジェクトを定義します。メソッドは onewayoneway void doFoo())でも同期でもかまいません。インターフェースが onewayoneway interface ITeleport {...})として定義されている場合、そのインターフェース内のすべてのメソッドは暗黙的に oneway になります。一方向のメソッドは非同期でディスパッチされ、結果を返すことができません。同じスレッドから同じバインダへの一方向のメソッドも連続して実行されます(なお、異なるスレッドで実行される可能性があります)。スレッドを設定する方法については、AIDL バックエンド スレッドの管理をご覧ください。

メソッドには 0 個以上の引数を指定できます。メソッドの引数は、inoutinout のいずれでもかまいません。これが引数の型にどう影響するかについては、AIDL バックエンドの方向性をご覧ください。

Parcelable

バックエンド固有の Parcelable を作成する方法については、AIDL バックエンドのカスタム Parcelable をご覧ください。

Android 10 以降では、AIDL で直接 Parcelable 定義がサポートされています。 このタイプの Parcelable は「構造化 Parcelable」と呼ばれます。構造化された安定版 AIDL が AIDL コンパイラと Android ビルドシステムでどのように関連しているかについては、構造化 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 インターフェース、Parcelable、共用体には、次のような整数と文字列の定数を含めることもできます。

    const @utf8InCpp String HAPPY = ":)";
    const String SAD = ":(";
    const byte BYTE_ME = 1;
    const int ANSWER = 6 * 7;

定数式

AIDL の定数、配列サイズ、列挙子は定数式を使って指定できます。式では、かっこを使用して演算をネストできます。定数式の値は、整数値または浮動小数点数値と組み合わせることができます。

truefalse のリテラルはブール値を表します。3.8 のように . はあるが接尾辞は付いていない値は、倍精度値と見なされます。浮動小数点数値には、2.4f のように f という接尾辞が付きます。l または L の接尾辞が付く整数は、64 ビット long 値を示します。それ以外の場合、整数値は、8 ビット(byte)、32 ビット(int)、64 ビット(long)の間の最小値を保持する符号付きの型を取ります。したがって、256int と見なされますが、255 + 1 はオーバーフローして byte 0 になります。0x3 などの 16 進数値は、まず 32 ビットと 64 ビットの間の最小値を保持する符号なしの型と解釈されてから、符号なしの値と再解釈されます。したがって、0xffffffffint 値の -1 になります。Android 13 以降では、byte 値を表すために 3u8 のように定数に接尾辞 u8 を追加できます。0xffu8 * 3 などの計算は byte 型の -3 と解釈されるのに対し、0xff * 3int 型の 765 と解釈されるため、この接尾辞は重要です。

サポートされている演算子には、C++ と Java のセマンティクスが含まれます。バイナリ演算子は、優先度が低いものから順に || && | ^ & == != < > <= >= << >> + - * / % です。単項演算子は + - ! ~ です。