Język AIDL jest luźno oparty na języku Java. Pliki określają kontrakt interfejsu oraz różne typy danych i stałe używane w tym kontrakcie.
Pakiet
Każdy plik AIDL zaczyna się od opcjonalnego pakietu, który odpowiada nazwom pakietów w różnych backendach. Deklaracja pakietu wygląda tak:
package my.package;
Podobnie jak w Javie, pliki AIDL muszą mieć strukturę folderów odpowiadającą ich pakietowi. Pliki z pakietem my.package
muszą znajdować się w folderze my/package/
.
Rodzaje
W plikach AIDL istnieje wiele miejsc, w których można określić typy. Aby uzyskać dokładną listę typów obsługiwanych w języku AIDL, zobacz AIDL backend types .
Adnotacje
Kilka części języka AIDL obsługuje adnotacje. Aby zapoznać się z listą adnotacji i miejscami ich zastosowania, zobacz Adnotacje AIDL .
Import
Aby używać typów zdefiniowanych w innych interfejsach, musisz najpierw dodać zależności w systemie kompilacji. W cc_*
i java_*
Soong, gdzie pliki .aidl
są używane bezpośrednio pod srcs
w kompilacjach platformy Android, możesz dodawać katalogi za pomocą pola aidl: { include_dirs: ... }
. Informacje o imporcie przy użyciu aidl_interface
można znaleźć tutaj .
Import wygląda tak:
import some.package.Foo; // explicit import
Podczas importowania typu w tym samym pakiecie pakiet można pominąć. Chociaż pominięcie pakietu może prowadzić do niejednoznacznych błędów importu, gdy typy są określone bez pakietu i umieszczane w globalnej przestrzeni nazw (ogólnie wszystkie typy powinny mieć przestrzeń nazw):
import Foo; // same as my.package.Foo
Definiowanie typów
Pliki AIDL ogólnie definiują typy, które są używane jako interfejs.
Interfejsy
Oto przykładowy interfejs AIDL:
interface ITeleport {
void teleport(Location baz, float speed);
String getName();
}
Interfejs definiuje obiekt za pomocą szeregu metod. Metody mogą być jednokierunkowe ( oneway
oneway void doFoo()
) lub synchroniczne. Jeśli interfejs jest zdefiniowany jako jednokierunkowy ( interfejs jednokierunkowy oneway
oneway interface ITeleport {...}
), wszystkie metody w nim są niejawnie oneway
. Metody jednokierunkowe są wysyłane asynchronicznie i nie mogą zwracać wyniku. Metody jednokierunkowe z tego samego wątku do tego samego spinacza są również gwarantowane do wykonania szeregowego (choć potencjalnie w różnych wątkach). Aby zapoznać się z dyskusją na temat konfigurowania wątków, zobacz Zarządzanie wątkami zaplecza AIDL .
Metody mogą mieć zero lub więcej argumentów. Argumenty metod mogą być in
, out
lub inout
. Aby zapoznać się z dyskusją na temat tego, jak wpływa to na typy argumentów, zobacz AIDL kierunkowość backendów .
Paczki
Aby uzyskać opis sposobu tworzenia działek specyficznych dla zaplecza, AIDL zawiera niestandardowe działki zaplecza .
Android 10 i nowsze obsługują deklaracje parcelable bezpośrednio w AIDL. Na przykład:
package my.package;
import my.package.Boo;
parcelable Baz {
@utf8InCpp String name = "baz";
Boo boo;
}
Związki
Android 12 i nowsze obsługują deklaracje związkowe. Na przykład:
package my.package;
import my.package.FooSettings;
import my.package.BarSettings;
union Settings {
FooSettings fooSettings;
BarSettings barSettings;
@utf8InCpp String str;
int number;
}
Wyliczenia
Android 11 i nowsze obsługują deklaracje wyliczenia. Na przykład:
package my.package;
enum Boo {
A = 1 * 4,
B = 3,
}
Deklaracje typu zagnieżdżonego
Android 13 i nowsze obsługują deklaracje typu zagnieżdżonego. Na przykład:
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
}
Stałe
Niestandardowe interfejsy AIDL, parcelable i unii mogą również zawierać stałe całkowite i łańcuchowe, takie jak:
const @utf8InCpp String HAPPY = ":)";
const String SAD = ":(";
const byte BYTE_ME = 1;
const int ANSWER = 6 * 7;
Wyrażenia stałe
Stałe AIDL, rozmiary tablic i moduły wyliczające można określić za pomocą wyrażeń stałych. Wyrażenia mogą używać nawiasów do zagnieżdżania operacji. Wartości wyrażeń stałych mogą być używane z wartościami całkowitymi lub zmiennoprzecinkowymi.
literały true
i false
reprezentują wartości logiczne. Wartości z .
ale bez sufiksu, takiego jak 3.8
, są uważane za wartości podwójne. Wartości zmiennoprzecinkowe mają przyrostek f
, na przykład 2.4f
. Wartość całkowita z sufiksem l
lub L
wskazuje na 64-bitową wartość. W przeciwnym razie wartości całek uzyskują najmniejszy typ ze znakiem z zachowaniem wartości między 8-bitowymi (bajtami), 32-bitowymi (int) i 64-bitowymi (long). Tak więc 256
jest uważane za int
, ale 255 + 1
przepełnia się na byte
0
. Wartości szesnastkowe, takie jak 0x3
, są najpierw interpretowane jako najmniejszy typ bez znaku zachowujący wartość między 32-bitową a 64-bitową, a następnie ponownie interpretowany jako wartości bez znaku. Tak więc 0xffffffff
ma wartość int
-1
. Począwszy od systemu Android 13, sufiks u8
można dodać do stałych, takich jak 3u8
, aby reprezentować wartość byte
. Ten przyrostek jest ważny, aby obliczenia, takie jak 0xffu8 * 3
, były interpretowane jako -3
z typem byte
, podczas gdy 0xff * 3
to 765
z typem int
.
Obsługiwane operatory mają semantykę C++ i Java. W kolejności od najniższego do najwyższego pierwszeństwa operatorami binarnymi są || && | ^ & == != < > <= >= << >> + - * / %
. Operatory jednoargumentowe to + - ! ~
.