Dado un archivo de interfaz HIDL, el backend Java HIDL genera interfaces Java, Stub y código Proxy. Admite todos los tipos escalares de HIDL ([ u
] int
{ 8,16,32,64}_t, float, double,
y enum
s), así como cadenas, interfaces, tipos de unión segura, tipos de estructuras y matrices y vectores de soportes compatibles. tipos de HIDL. El backend de Java HIDL NO admite tipos de unión o tipos fmq . Android 11 agrega soporte para los tipos de memory
y handle
.
Como el tiempo de ejecución de Java no admite el concepto de enteros sin signo de forma nativa, todos los tipos sin signo (y las enumeraciones basadas en ellos) se tratan silenciosamente como sus equivalentes con signo, es decir, uint32_t
se convierte en un int
en la interfaz de Java. No se realiza ninguna conversión de valor; el implementador en el lado de Java debe usar los valores firmados como si no estuvieran firmados.
Enumeraciones
Las enumeraciones no generan clases de enumeración de Java, sino que se traducen en clases internas que contienen una definición constante estática para cada caso de enumeración. Si la clase de enumeración se deriva de alguna otra clase de enumeración, hereda el tipo de almacenamiento de esa clase. Las enumeraciones basadas en un tipo de entero sin signo se reescriben en su equivalente con signo. Dado que el tipo subyacente es un primitivo, el valor predeterminado para los campos/variables de enumeración es cero incluso cuando no hay un enumerador cero.
Por ejemplo, un SomeBaseEnum
con un tipo de uint8_t
:
enum SomeBaseEnum : uint8_t { foo = 3 }; enum SomeEnum : SomeBaseEnum { quux = 33, goober = 127 };
… se convierte en:
public final class SomeBaseEnum { public static final byte foo = 3; } public final class SomeEnum { public static final byte foo = 3; public static final byte quux = 33; public static final byte goober = 127; }
Y:
enum SomeEnum : uint8_t { FIRST_CASE = 10, SECOND_CASE = 192 };
… se reescribe como:
public final class SomeEnum { static public final byte FIRST_CASE = 10; // no change static public final byte SECOND_CASE = -64; }
Instrumentos de cuerda
String
en Java son utf-8 o utf-16 pero se convierten a utf-8 como el tipo HIDL común cuando se transportan. Además, una String
no debe ser nula cuando se pasa a HIDL.
Mango y memoria
Android 11 presenta compatibilidad con Java para los tipos de handle
y memory
. Se traducen a android.os.NativeHandle
y android.os.HidlMemory
, respectivamente. Un identificador nulo se considera válido, mientras que una memoria nula no lo es.
En el código de servidor generado, la memoria recibida y los argumentos de identificador solo son válidos dentro del alcance de la invocación del método. Si la implementación del servidor quiere extender su vida útil, deben duplicarse usando sus respectivos métodos dup()
. La instancia devuelta se puede usar más allá de la invocación del método y debe cerrarse correctamente cuando termine.
En el código de cliente generado, los identificadores y las instancias de memoria que se envían como argumentos de entrada del método llamado no necesitan duplicarse ni mantenerse válidos después de que el método regrese. Sin embargo, los identificadores y las instancias de memoria que se reciben como argumentos de salida se duplican automáticamente mediante el código generado automáticamente y deben cerrarse correctamente cuando terminen. Esto es así tanto si esos argumentos devueltos aparecen como valores devueltos del método (en el caso de valor devuelto único) como si se usa el estilo de devolución de llamada síncrona (usado en el caso de valor devuelto múltiple).
Para obtener más información sobre la duplicación y el cierre, consulte la documentación de las clases de Java.
Matrices y vectores
Los arreglos se traducen a arreglos Java y los vectores se traducen a ArrayList<T>
donde T es el tipo de objeto apropiado, posiblemente envolviendo tipos escalares como vec<int32_t> => ArrayList<Integer>
). Por ejemplo:
takeAnArray(int32_t[3] array); returnAVector() generates (vec<int32_t> result);
… se convierte en:
void takeAnArray(int[] array); ArrayList<Integer> returnAVector();
Estructuras
Las estructuras se traducen a clases Java con un diseño similar. Por ejemplo:
struct Bar { vec<bool> someBools; }; struct Foo { int32_t a; int8_t b; float[10] c; Bar d; };
… se convierte en:
class Bar { public final ArrayList<Boolean> someBools = new ArrayList(); }; class Foo { public int a; public byte b; public final float[] c = new float[10]; public final Bar d = new Bar(); }
tipos declarados
Cada tipo de nivel superior declarado en types.hal
obtiene su propio archivo de salida .java (según lo requiere Java). Por ejemplo, el siguiente archivo types.hal
da como resultado la creación de dos archivos adicionales (Foo.java y Bar.java):
struct Foo { ... }; struct Bar { ... struct Baz { }; ... };
La definición de Baz vive en una clase interna estática de Bar (en Bar.java).