Die AIDL-Sprache basiert lose auf der Java-Sprache. Dateien geben einen Schnittstellenvertrag und verschiedene in diesem Vertrag verwendete Datentypen und Konstanten an.
Paket
Jede AIDL-Datei beginnt mit einem optionalen Paket, das den Paketnamen in verschiedenen Backends entspricht. Eine Paketdeklaration sieht so aus:
package my.package;
Ähnlich wie bei Java müssen sich AIDL-Dateien in einer Ordnerstruktur befinden, die zu ihrem Paket passt. Dateien mit dem Paket my.package
müssen sich im Ordner my/package/
befinden.
Typen
In AIDL-Dateien gibt es viele Stellen, an denen Typen angegeben werden können. Eine genaue Liste der Typen, die in der AIDL-Sprache unterstützt werden, finden Sie unter AIDL-Backend-Typen .
Anmerkungen
Mehrere Teile der AIDL-Sprache unterstützen Anmerkungen. Eine Liste der Anmerkungen und wo sie angewendet werden können, finden Sie unter AIDL-Anmerkungen .
Importe
Um in anderen Schnittstellen definierte Typen zu verwenden, müssen Sie zunächst 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 Verzeichnisse mithilfe des Felds aidl: { include_dirs: ... }
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. Allerdings kann das Weglassen des Pakets zu mehrdeutigen Importfehlern führen, wenn Typen ohne Paket angegeben und in den globalen Namespace gestellt werden (im Allgemeinen sollten alle Typen einen Namespace haben):
import Foo; // same as my.package.Foo
Typen definieren
AIDL-Dateien definieren im Allgemeinen 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. 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
. Oneway-Methoden werden asynchron versendet und können kein Ergebnis zurückgeben. Einwegmethoden vom selben Thread zum selben Binder werden garantiert auch seriell ausgeführt (allerdings möglicherweise in verschiedenen Threads). Eine Diskussion zum Einrichten von Threads finden Sie unter AIDL-Backends-Thread-Management .
Methoden können null oder mehr Argumente haben. Argumente für Methoden können in
, out
oder inout
sein. Eine Diskussion darüber, wie sich dies auf Argumenttypen auswirkt, finden Sie unter AIDL-Backend-Richtung .
Pakete
Eine Beschreibung zum Erstellen von Backend-spezifischen Parcelables finden Sie unter AIDL Backends Custom Parcelables .
Android 10 und höher unterstützen Paketdefinitionen direkt in AIDL. Diese Art von Parzelle wird als strukturierte Parzelle bezeichnet. Weitere Informationen darüber, wie strukturiertes und stabiles AIDL im AIDL-Compiler und unserem Build-System zusammenhängen, finden Sie unter Strukturiertes vs. stabiles AIDL .
Zum Beispiel:
package my.package;
import my.package.Boo;
parcelable Baz {
@utf8InCpp String name = "baz";
Boo boo;
}
Gewerkschaften
Android 12 und höher unterstützen Gewerkschaftserklärungen. Zum 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. Zum Beispiel:
package my.package;
enum Boo {
A = 1 * 4,
B = 3,
}
Verschachtelte Typdeklarationen
Android 13 und höher unterstützen verschachtelte Typdeklarationen. Zum 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 String-Konstanten enthalten, wie zum Beispiel:
const @utf8InCpp String HAPPY = ":)";
const String SAD = ":(";
const byte BYTE_ME = 1;
const int ANSWER = 6 * 7;
Konstante Ausdrücke
AIDL-Konstanten, Array-Größen und Enumeratoren können mithilfe konstanter Ausdrücke angegeben werden. Ausdrücke können Klammern verwenden, um Vorgänge zu verschachteln. Konstante Ausdruckswerte können mit Integral- oder Float-Werten verwendet werden.
Die Literale true
und false
stellen boolesche Werte dar. Werte mit einem .
aber ohne Suffix, wie z. B. 3.8
, gelten als doppelte Werte. Float-Werte 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 Integralwerte den kleinsten werterhaltenden vorzeichenbehafteten Typ zwischen 8 Bit (Byte), 32 Bit (int) und 64 Bit (long). Daher wird 256
als int
betrachtet, aber 255 + 1
läuft über und ergibt das byte
0
. Hexadezimalwerte wie 0x3
werden zunächst 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
zu Konstanten wie 3u8
hinzugefügt werden, um einen byte
darzustellen. Dieses Suffix ist wichtig, damit eine Berechnung wie 0xffu8 * 3
beim Typ byte
als -3
interpretiert wird, während 0xff * 3
beim Typ int
765
ist.
Unterstützte Operatoren haben C++- und Java-Semantik. In der Reihenfolge von der niedrigsten zur höchsten Priorität sind die binären Operatoren || && | ^ & == != < > <= >= << >> + - * / %
. Unäre Operatoren sind + - ! ~
.