Langage AIDL

Le langage AIDL est vaguement basé sur le langage Java. Les fichiers spécifient un contrat d'interface, ainsi que divers types de données et constantes utilisés dans ce contrat.

Package

Chaque fichier AIDL commence par un package facultatif qui correspond aux noms de package dans différents backends. Une déclaration de package se présente comme suit:

    package my.package;

Comme pour Java, les fichiers AIDL doivent se trouver dans une structure de dossiers correspondant à leur package. Les fichiers avec le package my.package doivent se trouver dans le dossier my/package/.

Types

Dans les fichiers AIDL, les types peuvent être spécifiés à de nombreux endroits. Pour obtenir la liste exacte des types de backends compatibles avec le langage AIDL, consultez la page Types de backends AIDL.

Annotations

Plusieurs parties des annotations de prise en charge du langage AIDL Pour obtenir la liste des annotations et des emplacements où elles peuvent être appliquées, consultez la page Annotations AIDL.

Importations

Pour utiliser des types définis dans d'autres interfaces, vous devez d'abord ajouter des dépendances dans le système de compilation. Dans les modules Soong cc_* et java_*, où les fichiers .aidl sont utilisés directement sous srcs dans les builds de la plate-forme Android, vous pouvez ajouter des répertoires à l'aide du champ aidl: { include_dirs: ... }. Pour les importations à l'aide de aidl_interface, cliquez ici.

Une importation se présente comme suit:

    import some.package.Foo;  // explicit import

Lorsque vous importez un type dans le même package, le package peut être omis. Toutefois, l'omission du package peut entraîner des erreurs d'importation ambiguës lorsque les types sont spécifiés sans package et placés dans l'espace de noms global (en général, tous les types doivent être associés à un espace de noms):

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

Définir les types

Les fichiers AIDL définissent généralement des types qui sont utilisés comme une interface.

Interfaces

Voici un exemple d'interface AIDL:

    interface ITeleport {
        void teleport(Location baz, float speed);
        String getName();
    }

Une interface définit un objet avec une série de méthodes. Les méthodes peuvent être oneway (oneway void doFoo()) ou synchrones. Si une interface est définie sur oneway (oneway interface ITeleport {...}), toutes les méthodes qu'elle contient sont implicitement oneway. Les méthodes à sens unique sont envoyées de manière asynchrone et ne peuvent pas renvoyer de résultat. Les méthodes unidirectionnelles du même thread au même liaison s'exécutent également en série (bien que potentiellement sur des threads différents). Pour en savoir plus sur la configuration des threads, consultez la section Gestion des threads des backends AIDL.

Les méthodes peuvent avoir zéro ou plusieurs arguments. Les arguments des méthodes peuvent être in, out ou inout. Pour en savoir plus sur l'impact de ce changement sur les types d'arguments, consultez la section Orientation des backends AIDL.

Éléments Parcelables

Pour savoir comment créer des parcelables spécifiques à un backend, consultez la page sur les parcelables personnalisés pour les backends AIDL.

Android 10 et les versions ultérieures sont compatibles avec les définitions parcelables directement dans AIDL. Ce type d'élément morcelé est appelé "parcelable structuré". Pour en savoir plus sur la relation entre AIDL structuré et stable dans le compilateur AIDL et notre système de compilation, consultez la section AIDL structuré et stable.

Par exemple :

    package my.package;

    import my.package.Boo;

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

Union

Android 12 et versions ultérieures sont compatibles avec les déclarations d'union. Par exemple :

    package my.package;

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

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

Énumérations

Android 11 ou version ultérieure est compatible avec les déclarations d'énumération. Par exemple :

    package my.package;

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

Déclarations des types imbriqués

Android 13 et versions ultérieures sont compatibles avec les déclarations de types imbriqués. Par exemple :

    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
    }

Constantes

Les interfaces, les parcelles et les unions AIDL personnalisés peuvent également contenir des constantes d'entiers et de chaînes, telles que:

    const @utf8InCpp String HAPPY = ":)";
    const String SAD = ":(";
    const byte BYTE_ME = 1;
    const int ANSWER = 6 * 7;

Expressions constantes

Les constantes AIDL, les tailles de tableaux et les énumérateurs peuvent être spécifiés à l'aide d'expressions constantes. Les expressions peuvent utiliser des parenthèses pour imbriquer des opérations. Les valeurs d'expression constantes peuvent être utilisées avec des valeurs intégrales ou flottantes.

Les littéraux true et false représentent des valeurs booléennes. Les valeurs avec un ., mais sans suffixe, comme 3.8, sont considérées comme des valeurs doubles. Les valeurs flottantes comportent le suffixe f, par exemple 2.4f. Une valeur intégrale avec le suffixe l ou L indique une valeur longue de 64 bits. Sinon, les valeurs intégrales obtiennent le plus petit type signé préservant la valeur entre 8 bits (octet), 32 bits (int) et 64 bits (long). 256 est donc considéré comme un int, mais 255 + 1 déborde pour être le 0 byte. Les valeurs hexadécimales, telles que 0x3, sont d'abord interprétées comme le plus petit type non signé préservant la valeur entre 32 bits et 64 bits, puis réinterprétées en tant que valeurs non signées. Ainsi, 0xffffffff a la valeur int -1. À partir d'Android 13, le suffixe u8 peut être ajouté à des constantes, telles que 3u8, pour représenter une valeur byte. Ce suffixe est important pour qu'un calcul, tel que 0xffu8 * 3, soit interprété comme -3 de type byte, tandis que 0xff * 3 est 765 de type int.

Les opérateurs compatibles ont une sémantique C++ et Java. Par ordre de priorité croissante, les opérateurs binaires sont || && | ^ & == != < > <= >= << >> + - * / %. Les opérateurs unaires sont + - ! ~.