Idioma AIDL

El lenguaje AIDL se basa libremente en el lenguaje Java. Los archivos especifican un contrato de interfaz y varios tipos de datos y constantes utilizados en este contrato.

Paquete

Todos los archivos AIDL comienzan con un paquete opcional que corresponde a los nombres de los paquetes en varios backends. Una declaración de paquete se ve así:

    package my.package;

Similar a Java, los archivos AIDL deben estar en una estructura de carpetas que coincida con su paquete. Los archivos con el paquete my.package deben estar en la carpeta my/package/ .

Tipos

En los archivos AIDL, hay muchos lugares donde se pueden especificar los tipos. Para obtener una lista exacta de los tipos admitidos en el lenguaje AIDL, consulte Tipos de backends de AIDL .

Anotaciones

Varias partes del lenguaje AIDL admiten anotaciones. Para obtener una lista de anotaciones y dónde se pueden aplicar, consulte Anotaciones AIDL .

Importaciones

Para usar tipos definidos en otras interfaces, primero debe agregar dependencias en el sistema de compilación. En cc_* y java_* Soong, donde los archivos .aidl se usan directamente bajo srcs en las compilaciones de la plataforma Android, puede agregar directorios usando el campo aidl: { include_dirs: ... } . Para importaciones usando aidl_interface , vea aquí .

Una importación se ve así:

    import some.package.Foo;  // explicit import

Al importar un tipo en el mismo paquete, se puede omitir el paquete. Sin embargo, omitir el paquete puede generar errores de importación ambiguos cuando los tipos se especifican sin un paquete y se colocan en el espacio de nombres global (por lo general, todos los tipos deben tener un espacio de nombres):

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

Definición de tipos

Los archivos AIDL generalmente definen tipos que se utilizan como interfaz.

Interfaces

Aquí hay un ejemplo de interfaz AIDL:

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

Una interfaz define un objeto con una serie de métodos. Los métodos pueden ser oneway ( oneway void doFoo() ) o síncronos. Si una interfaz se define como oneway oneway interface ITeleport {...} ), entonces todos los métodos en ella son implícitamente oneway . Los métodos unidireccionales se envían de forma asincrónica y no pueden devolver un resultado. También se garantiza que los métodos unidireccionales del mismo subproceso al mismo enlazador se ejecuten en serie (aunque potencialmente en diferentes subprocesos). Para una discusión sobre cómo configurar subprocesos, consulte Administración de subprocesos de backends de AIDL .

Los métodos pueden tener cero o más argumentos. Los argumentos de los métodos pueden ser in , out o inout . Para ver una discusión sobre cómo afecta esto a los tipos de argumentos, consulte Direccionalidad de los backends de AIDL .

Encomendables

Para obtener una descripción de cómo crear parcelables específicos de back-end, AIDL backends parcelables personalizados .

Android 10 y versiones posteriores admiten declaraciones parcelables directamente en AIDL. Por ejemplo:

    package my.package;

    import my.package.Boo;

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

sindicatos

Android 12 y versiones posteriores admiten declaraciones de unión. Por ejemplo:

    package my.package;

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

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

Enumeraciones

Android 11 y versiones posteriores admiten declaraciones de enumeración. Por ejemplo:

    package my.package;

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

Declaraciones de tipos anidados

Android T (AOSP experimental) y versiones posteriores admiten declaraciones de tipos anidados. Por ejemplo:

    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

Las interfaces AIDL personalizadas, los paquetes y las uniones también pueden contener enteros y constantes de cadena, como:

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

Expresiones constantes

Las constantes AIDL, los tamaños de matriz y los enumeradores se pueden especificar mediante expresiones constantes. Las expresiones pueden usar paréntesis para anidar operaciones. Los valores de expresión constante se pueden usar con valores integrales o flotantes.

los literales true y false representan valores booleanos. Valores con un . pero sin un sufijo, como 3.8 , se consideran valores dobles. Los valores flotantes tienen el sufijo f , como 2.4f . Un valor integral con el sufijo l o L indica un valor largo de 64 bits. De lo contrario, los valores integrales obtienen el tipo con signo que preserva el valor más pequeño entre 8 bits (byte), 32 bits (int) y 64 bits (largo). Entonces 256 se considera un int , pero 255 + 1 se desborda para ser el byte 0 . Los valores hexadecimales, como 0x3 , se interpretan primero como el tipo sin signo que conserva el valor más pequeño entre 32 bits y 64 bits y luego se reinterpretan como valores sin signo. Entonces, 0xffffffff tiene el valor int -1 . A partir de Android T (AOSP experimental), el sufijo u8 se puede agregar a las constantes, como 3u8 , para representar un valor de byte . Este sufijo es importante para que un cálculo, como 0xffu8 * 3 , se interprete como -3 con tipo byte mientras que 0xff * 3 es 765 con tipo int .

Los operadores admitidos tienen semántica C++ y Java. En orden de menor a mayor precedencia, los operadores binarios son || && | ^ & == != < > <= >= << >> + - * / % . Los operadores unarios son + - ! ~ .