AIDL-Sprache

Die Sprache AIDL basiert grob auf der Sprache Java. In den Dateien werden ein Schnittstellenvertrag sowie verschiedene Datentypen und -konstanten definiert, die in diesem Vertrag verwendet werden.

Aufmachung

Jede AIDL-Datei beginnt mit einem optionalen Paket, das den Paketnamen in verschiedenen Back-Ends entspricht. Eine Paketdeklaration sieht so aus:

    package my.package;

Ähnlich wie bei Java müssen sich AIDL-Dateien in einer Ordnerstruktur befinden, die ihrem Paket entspricht. Dateien mit dem Paket „my.package“ müssen sich im Ordner „my/package/“ befinden.

Typen

In AIDL-Dateien können an vielen Stellen Typen angegeben werden. Eine genaue Liste der Typen, die in der AIDL-Sprache unterstützt werden, finden Sie unter AIDL-Back-End-Typen.

Anmerkungen

Mehrere Teile der AIDL-Sprachunterstützung Annotationen. Eine Liste der Annotationen und wo sie angewendet werden können, finden Sie unter AIDL-Annotationen.

Importe

Wenn Sie Typen verwenden möchten, die in anderen Schnittstellen definiert sind, müssen Sie zuerst Abhängigkeiten im Build-System hinzufügen. In cc_*- und java_*-Soong-Modulen, in denen .aidl-Dateien direkt unter srcs in Android-Plattform-Builds verwendet werden, können Sie mithilfe des Felds aidl: { include_dirs: ... } Verzeichnisse hinzufügen. Informationen zu Importen mit aidl_interface finden Sie hier.

Ein Import sieht so aus:

    import some.package.Foo;  // explicit import

Beim Importieren eines Typs im selben Paket kann das Paket weggelassen werden. Das Weglassen des Pakets kann jedoch zu mehrdeutigen Importfehlern führen, wenn Typen ohne Paket angegeben und im globalen Namespace abgelegt werden (im Allgemeinen sollten alle Typen mit einem Namespace versehen werden):

    import Foo;  // same as my.package.Foo

Typen definieren

AIDL-Dateien definieren in der Regel Typen, die als Schnittstelle verwendet werden.

Schnittstellen

Hier ist ein Beispiel für eine AIDL-Schnittstelle:

    interface ITeleport {
        void teleport(Location baz, float speed);
        String getName();
    }

Eine Schnittstelle definiert ein Objekt mit einer Reihe von Methoden. Die Methoden können entweder oneway (oneway void doFoo()) oder synchron sein. Wenn eine Schnittstelle als oneway (oneway interface ITeleport {...}) definiert ist, sind alle darin enthaltenen Methoden implizit oneway. Einwegmethoden werden asynchron weitergeleitet und können kein Ergebnis zurückgeben. Einwegmethoden vom selben Thread in denselben Binder werden auch nacheinander ausgeführt (möglicherweise auf verschiedenen Threads). Informationen zum Einrichten von Threads finden Sie unter Thread-Management für AIDL-Back-Ends.

Methoden können null oder mehr Argumente haben. Argumente für Methoden können in, out oder inout sein. Wie sich dies auf Argumenttypen auswirkt, wird unter Richtung von AIDL-Back-Ends erläutert.

Parcelables

Eine Beschreibung zum Erstellen von Back-End-spezifischen Paketen finden Sie unter Benutzerdefinierte AIDL-Back-Ends.

Android 10 und höher unterstützen Paketdefinitionen direkt in AIDL. Diese Art von Parcelable wird als strukturiertes Paket bezeichnet. Weitere Informationen dazu, wie strukturierte und stabile AIDL im AIDL-Compiler und in unserem Build-System zusammenhängen, finden Sie unter Strukturierter und stabiler AIDL.

Beispiel:

    package my.package;

    import my.package.Boo;

    parcelable Baz {
        @utf8InCpp String name = "baz";
        Boo boo;
    }

Gewerkschaften

Android 12 und höher unterstützen Union-Deklarationen. Beispiel:

    package my.package;

    import my.package.FooSettings;
    import my.package.BarSettings;

    union Settings {
        FooSettings fooSettings;
        BarSettings barSettings;
        @utf8InCpp String str;
        int number;
    }

Aufzählungen

Android 11 und höher unterstützen enum-Deklarationen. Beispiel:

    package my.package;

    enum Boo {
        A = 1 * 4,
        B = 3,
    }

Verschachtelte Typdeklarationen

Android 13 und höher unterstützen verschachtelte Typdeklarationen. Beispiel:

    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
    }

Konstanten

Benutzerdefinierte AIDL-Schnittstellen, Parcelables und Unions können auch Ganzzahl- und Stringkonstanten enthalten. Beispiele:

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

Konstantenausdrücke

AIDL-Konstanten, Arraygrößen und Enumeratoren können mithilfe von konstanten Ausdrücken angegeben werden. In Ausdrücken können Klammern verwendet werden, um Operationen zu verschachteln. Konstantenausdruckwerte können mit ganzzahligen oder Gleitkommawerten verwendet werden.

Die Literale true und false stellen boolesche Werte dar. Werte mit einer ., aber ohne Suffix, z. B. 3.8, werden als doppelte Werte angesehen. Gleitkommawerte haben das Suffix f, z. B. 2.4f. Ein ganzzahliger Wert mit dem Suffix l oder L gibt einen 64 Bit langen Wert an. Andernfalls erhalten Integralewerte den kleinsten werterhaltenden Vorzeichentyp zwischen 8 Bit (Byte), 32 Bit (int) und 64 Bit (lang). Daher wird 256 als int betrachtet, aber 255 + 1 läuft über byte als 0 aus. Hex-Werte wie 0x3 werden zuerst als der kleinste werterhaltende vorzeichenlose Typ zwischen 32 Bit und 64 Bit interpretiert und dann als vorzeichenlose Werte neu interpretiert. 0xffffffff hat also den int-Wert -1. Ab Android 13 kann das Suffix u8 Konstanten wie 3u8 hinzugefügt werden, um einen byte-Wert darzustellen. Dieses Suffix ist wichtig, damit eine Berechnung wie 0xffu8 * 3 als -3 mit dem Typ byte interpretiert wird, während 0xff * 3 765 vom Typ int ist.

Unterstützte Operatoren bieten C++- und Java-Semantik. In der Reihenfolge von der niedrigsten zur höchsten Priorität sind die binären Operatoren || && | ^ & == != < > <= >= << >> + - * / %. Unäre Operatoren sind + - ! ~.