Linguaggio AIDL

Il linguaggio AIDL è vagamente basato sul linguaggio Java. I file specificano un contratto di interfaccia e vari tipi di dati e costanti utilizzate in questo contratto.

Pacco

Ogni file AIDL inizia con un pacchetto facoltativo che corrisponde ai nomi dei pacchetti nei vari backend. Una dichiarazione relativa al pacchetto è simile alla seguente:

    package my.package;

Analogamente a quanto avviene con 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 esistono molte posizioni in cui è possibile specificare i tipi. Per un elenco esatto dei tipi supportati nel linguaggio AIDL, consulta Tipi di backend AIDL.

Annotazioni

Diverse parti del linguaggio AIDL supportano le annotazioni. Per un elenco di annotazioni e dove possono essere applicate, consulta Annotazioni AIDL.

Importazioni

Per utilizzare i tipi definiti in altre interfacce, devi prima aggiungere le dipendenze nel sistema di build. Nei moduli presto cc_* e java_*, dove i file .aidl vengono utilizzati direttamente in srcs nelle build della piattaforma Android, puoi aggiungere directory utilizzando il campo aidl: { include_dirs: ... }. Per le importazioni utilizzando aidl_interface, visita questa pagina.

Un'importazione ha il seguente aspetto:

    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ò causare errori di importazione ambigui quando i tipi vengono specificati senza un pacchetto e inseriti nello spazio dei nomi globale (in genere, tutti i tipi devono avere uno spazio dei nomi):

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

Definisci i tipi

I file AIDL in genere definiscono i tipi 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 (oneway void doFoo()) o sincroni. Se un'interfaccia è definita come oneway (oneway interface ITeleport {...}), tutti i metodi al suo interno 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 vengono eseguiti in serie (anche se potenzialmente su thread diversi). Per una discussione su come configurare i thread, consulta Gestione dei thread dei backend AIDL.

I metodi possono avere zero o più argomenti. Gli argomenti dei metodi possono essere in, out o inout. Per una discussione su come questo influisce sui tipi di argomenti, consulta Direzionalità dei backend AIDL.

Lotti da parte

Per una descrizione di come creare particella specifiche per i backend, parcelabili personalizzati dei backend AIDL.

Android 10 e versioni successive supportano definizioni parcelabili direttamente in AIDL. Questo tipo di "parcelable" è chiamato "parcelable" strutturato. Per ulteriori informazioni su come i dati AIDL strutturati e stabili sono correlati nel compilatore AIDL e nel nostro sistema di compilazione, consulta AIDL strutturato e stabile.

Ecco alcuni esempi:

    package my.package;

    import my.package.Boo;

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

Sindacati

Android 12 e versioni successive supportano le dichiarazioni dei sindacati. Ecco alcuni esempi:

    package my.package;

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

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

Enumerazionis

Dichiarazioni enum del supporto per Android 11 e versioni successive. Ecco alcuni esempi:

    package my.package;

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

Dichiarazioni dei tipi nidificati

Android 13 e versioni successive supportano le dichiarazioni dei tipi nidificate. Ecco alcuni esempi:

    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, i partizionabili e le unioni personalizzate AIDL possono contenere anche numeri interi e costanti stringa, 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 degli array e i enumeratori possono essere specificati utilizzando espressioni costanti. Le espressioni possono utilizzare le parentesi per nidificare le operazioni. I valori di espressione costante possono essere utilizzati con valori integrali o in virgola mobile.

I valori letterali true e false rappresentano valori booleani. I valori con . ma senza suffisso, come 3.8, sono considerati valori doppi. I valori in virgola mobile 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 firmato con protezione del valore più piccolo tra 8 bit (byte), 32 bit (int) e 64 bit (lungo). Pertanto 256 è considerato un int, ma 255 + 1 esegue l'overflow come byte 0. I valori esadecimali, come 0x3, vengono prima interpretati come il tipo senza segno più piccolo per la tutela del valore tra 32 e 64 bit, quindi reinterpretati come valori senza firma. Pertanto, 0xffffffff ha il valore int -1. A partire da Android 13, il suffisso u8 può essere aggiunto a costanti, ad esempio 3u8, per rappresentare un valore byte. Questo suffisso è importante, pertanto un calcolo, ad esempio 0xffu8 * 3, viene interpretato come -3 con il tipo byte, mentre 0xff * 3 è 765 con il tipo int.

Gli operatori supportati hanno una semantica C++ e Java. A partire dalla precedenza più bassa con quella più alta, gli operatori binari sono || && | ^ & == != < > <= >= << >> + - * / %. Gli operatori unari sono + - ! ~.