Linguaggio AIDL

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 assomiglia a questa:

    package my.package;

Similmente 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, consulta Tipi di backend AIDL .

Annotazioni

Diverse parti del linguaggio AIDL supportano le annotazioni. Per un elenco delle 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 moduli cc_* e java_* Soong, in cui i file .aidl vengono utilizzati direttamente in srcs nelle build della piattaforma Android, è possibile aggiungere directory utilizzando il campo aidl: { include_dirs: ... } . Per le importazioni utilizzando aidl_interface , vedere qui .

Un'importazione si presenta così:

    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 ( oneway void doFoo() ) o sincroni. Se un'interfaccia è definita come 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. È inoltre garantita l'esecuzione in serie dei metodi unidirezionali dallo stesso thread allo stesso raccoglitore (sebbene potenzialmente su thread diversi). Per una discussione su come impostare i thread, consulta Gestione dei thread nei 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 ciò influisce sui tipi di argomenti, vedere Direzionalità dei backend AIDL .

Parcellabili

Per una descrizione di come creare parcelables specifici del backend, AIDL backends custom parcelables .

Android 10 e versioni successive supportano le definizioni parcellabili direttamente in AIDL. Questo tipo di parcellabile è chiamato parcellabile strutturato. Per ulteriori informazioni sulla relazione tra AIDL strutturato e stabile nel compilatore AIDL e nel nostro sistema di compilazione, vedere AIDL strutturato e AIDL stabile .

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;
    }

Enumerazioni

Android 11 e versioni successive supportano le dichiarazioni di enumerazione. Per esempio:

    package my.package;

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

Dichiarazioni di tipo nidificato

Android 13 e versioni successive supportano le dichiarazioni di tipo annidato. 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, i parcelable e le unioni AIDL personalizzate possono contenere anche costanti intere e stringa, come:

    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 gli enumeratori possono essere specificati utilizzando espressioni costanti. Le espressioni possono utilizzare parentesi per nidificare le operazioni. I valori dell'espressione costante possono essere utilizzati con valori integrali o float.

i valori letterali true e false rappresentano valori booleani. Valori con . ma senza suffisso, come 3.8 , sono considerati valori doppi. I valori float hanno il suffisso f , come 2.4f . Un valore integrale con il suffisso l o L indica un valore lungo 64 bit. In caso contrario, i valori integrali ottengono il tipo con segno con conservazione del valore più piccolo tra 8 bit (byte), 32 bit (int) e 64 bit (long). Quindi 256 è considerato un int , ma 255 + 1 eccede e diventa il byte 0 . I valori esadecimali, come 0x3 , vengono prima interpretati come il tipo senza segno con conservazione del valore più piccolo 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 alle costanti, come 3u8 , per rappresentare un valore 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 la semantica C++ e Java. In ordine dalla precedenza più bassa a quella più alta, gli operatori binari sono || && | ^ & == != < > <= >= << >> + - * / % . Gli operatori unari sono + - ! ~ .