Il linguaggio AIDL è vagamente basato sul linguaggio Java. I file specificano un contratto di interfaccia e vari tipi di dati e costanti utilizzati in questo contratto.
Pacchetto
Ogni file AIDL inizia con un pacchetto opzionale che corrisponde ai nomi dei pacchetti in vari backend. Una dichiarazione di pacchetto si presenta così:
package my.package;
Simile a Java, i file AIDL devono trovarsi in una struttura di cartelle corrispondente al loro pacchetto. I file con il pacchetto my.package
devono trovarsi nella cartella my/package/
.
Tipi
Nei file AIDL, ci sono molti posti in cui è possibile specificare i tipi. Per un elenco esatto dei tipi supportati nel linguaggio AIDL, vedere Tipi di backend AIDL .
Annotazioni
Diverse parti del linguaggio AIDL supportano le annotazioni. Per un elenco di annotazioni e dove possono essere applicate, vedere Annotazioni AIDL .
Importazioni
Per utilizzare i tipi definiti in altre interfacce, devi prima aggiungere le dipendenze nel sistema di compilazione. Nei cc_*
e java_*
Soong, in cui i file .aidl
vengono utilizzati direttamente sotto srcs
nelle build della piattaforma Android, puoi aggiungere directory utilizzando il campo aidl: { include_dirs: ... }
. Per le importazioni che utilizzano aidl_interface
, vedere qui .
Un'importazione è simile a questa:
import some.package.Foo; // explicit import
Quando si importa un tipo nello stesso pacchetto, il pacchetto può essere omesso. Tuttavia, l'omissione del pacchetto può portare a errori di importazione ambigui quando i tipi vengono specificati senza un pacchetto e inseriti nello spazio dei nomi globale (generalmente tutti i tipi dovrebbero avere uno spazio dei nomi):
import Foo; // same as my.package.Foo
Definizione dei tipi
I file AIDL generalmente definiscono i tipi che vengono utilizzati come interfaccia.
Interfacce
Ecco un esempio di interfaccia AIDL:
interface ITeleport {
void teleport(Location baz, float speed);
String getName();
}
Un'interfaccia definisce un oggetto con una serie di metodi. I metodi possono essere oneway void doFoo()
oneway
o sincroni. Se un'interfaccia è definita come unidirezionale (interfaccia unidirezionale oneway
oneway interface ITeleport {...}
), tutti i metodi in essa contenuti sono implicitamente oneway
. I metodi unidirezionali vengono inviati in modo asincrono e non possono restituire un risultato. Anche i metodi unidirezionali dallo stesso thread allo stesso raccoglitore sono garantiti per l'esecuzione in serie (sebbene potenzialmente su thread diversi). Per una discussione su come impostare i thread, vedere Gestione dei thread dei back-end AIDL .
I metodi possono avere zero o più argomenti. Gli argomenti dei metodi possono essere in
, out
o inout
. Per una discussione su come ciò influisca sui tipi di argomenti, vedere la direzionalità dei backend AIDL .
Parcellabili
Per una descrizione di come creare parcelable specifici per il back-end, AIDL back-end custom parcelables .
Android 10 e versioni successive supportano le dichiarazioni parcelable direttamente in AIDL. Per esempio:
package my.package;
import my.package.Boo;
parcelable Baz {
@utf8InCpp String name = "baz";
Boo boo;
}
sindacati
Android 12 e versioni successive supportano le dichiarazioni sindacali. Per esempio:
package my.package;
import my.package.FooSettings;
import my.package.BarSettings;
union Settings {
FooSettings fooSettings;
BarSettings barSettings;
@utf8InCpp String str;
int number;
}
Enum
Android 11 e versioni successive supportano le dichiarazioni enum. Per esempio:
package my.package;
enum Boo {
A = 1 * 4,
B = 3,
}
Dichiarazioni di tipo annidato
Android 13 e versioni successive supportano le dichiarazioni di tipo nidificato. Per esempio:
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
}
Costanti
Le interfacce AIDL personalizzate, i pacchettizzabili e le unioni possono anche contenere costanti intere e stringhe, come ad esempio:
const @utf8InCpp String HAPPY = ":)";
const String SAD = ":(";
const byte BYTE_ME = 1;
const int ANSWER = 6 * 7;
Espressioni costanti
Le costanti AIDL, le dimensioni dell'array e gli enumeratori possono essere specificati utilizzando espressioni costanti. Le espressioni possono utilizzare le parentesi per annidare le operazioni. I valori di espressione costante possono essere utilizzati con valori interi o float.
i valori letterali true
e false
rappresentano valori booleani. Valori con un .
ma senza un suffisso, come 3.8
, sono considerati valori doppi. I valori float hanno il suffisso f
, ad esempio 2.4f
. Un valore integrale con il suffisso l
o L
indica un valore lungo a 64 bit. In caso contrario, i valori integrali ottengono il tipo con segno di conservazione del valore più piccolo compreso tra 8 bit (byte), 32 bit (int) e 64 bit (long). Quindi 256
è considerato un int
, ma 255 + 1
overflow è il byte
0
. I valori esadecimali, ad esempio 0x3
, vengono prima interpretati come il tipo senza segno più piccolo che preserva il valore tra 32 bit e 64 bit e quindi reinterpretati come valori senza segno. Quindi, 0xffffffff
ha il valore int
-1
. A partire da Android 13, il suffisso u8
può essere aggiunto a costanti, come 3u8
, per rappresentare un valore di byte
. Questo suffisso è importante in modo che un calcolo, come 0xffu8 * 3
, venga interpretato come -3
con tipo byte
mentre 0xff * 3
è 765
con tipo int
.
Gli operatori supportati hanno semantica C++ e Java. In ordine dalla precedenza più bassa a quella più alta, gli operatori binari sono || && | ^ & == != < > <= >= << >> + - * / %
. Gli operatori unari sono + - ! ~
.