Dato un file di interfaccia HIDL, il backend Java HIDL genera interfacce Java,
codice stub e proxy. Supporta tutti i tipi HIDL scalari
([u
]int
{8,16,32,64}_t, float, double,
e
enum
s), nonché stringhe, interfacce, tipi safe_union, tipi struct
e array e vettori di tipi HIDL supportati. Il backend HIDL Java
NON supporta i tipi unione o fmq. Android
11 aggiunge il supporto per i tipi memory
e
handle
.
Poiché Java Runtime non supporta nativamente il concetto di numeri interi senza segno,
tutti i tipi senza segno (e le enumerazioni basate su di essi) vengono trattati silenziosamente come i loro
equivalenti con segno, ovvero uint32_t
diventa int
nell'interfaccia Java. Non viene eseguita alcuna conversione di valori; l'implementatore sul lato Java deve utilizzare i valori firmati come se fossero non firmati.
Enumerazionis
Gli enum non generano classi enum Java, ma vengono invece tradotti in classi interne contenenti una definizione di costante statica per ogni caso di enum. Se la classe enum deriva da un'altra classe enum, eredita il tipo di archiviazione di quella classe. Le enumerazioni basate su un tipo di numero intero senza segno vengono riscritte nel loro equivalente con segno. Poiché il tipo sottostante è primitivo, il valore predefinito per i campi/le variabili enum è zero anche quando non è presente un enumeratore zero.
Ad esempio, un SomeBaseEnum
con un tipo di
uint8_t
:
enum SomeBaseEnum : uint8_t { foo = 3 }; enum SomeEnum : SomeBaseEnum { quux = 33, goober = 127 };
… diventa:
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; }
E:
enum SomeEnum : uint8_t { FIRST_CASE = 10, SECOND_CASE = 192 };
… viene riscritto come:
public final class SomeEnum { static public final byte FIRST_CASE = 10; // no change static public final byte SECOND_CASE = -64; }
Stringhe
String
in Java è utf-8 o utf-16, ma viene convertito in utf-8
come tipo HIDL comune durante il trasporto. Inoltre, String
non deve essere nullo quando viene passato a HIDL.
Maniglia e memoria
Android 11 introduce il supporto Java per i tipi handle
e
memory
. Vengono tradotti in android.os.NativeHandle
e
android.os.HidlMemory
, rispettivamente. Un handle nullo è considerato valido, mentre una memoria nulla no.
Nel codice server generato, gli argomenti di memoria e handle ricevuti sono validi solo
nell'ambito dell'invocazione del metodo. Se l'implementazione del server vuole estendere la propria
durata, deve essere duplicata utilizzando i rispettivi metodi dup()
. L'istanza restituita può essere utilizzata oltre l'invocazione del metodo e deve essere chiusa correttamente al termine dell'operazione.
Nel codice client generato, gli handle e le istanze di memoria che vengono inviati come argomenti di input del metodo chiamato non devono essere duplicati né mantenuti validi dopo la restituzione del metodo. Tuttavia, gli handle e le istanze di memoria che vengono ricevuti come argomenti di output vengono duplicati automaticamente dal codice generato automaticamente e devono essere chiusi correttamente al termine dell'utilizzo. Ciò vale sia che questi argomenti di ritorno vengano visualizzati come valori restituiti del metodo (nel caso di un singolo valore restituito) sia che utilizzino lo stile di callback sincrono (utilizzato nel caso di più valori restituiti).
Per ulteriori informazioni sulla duplicazione e sulla chiusura, consulta la documentazione delle classi Java.
Array e vettori
Gli array vengono convertiti in array Java e i vettori vengono convertiti in
ArrayList<T>
, dove T è il tipo di oggetto appropriato, che potrebbe
includere tipi scalari come vec<int32_t> =>
ArrayList<Integer>
. Ad esempio:
takeAnArray(int32_t[3] array); returnAVector() generates (vec<int32_t> result);
… diventa:
void takeAnArray(int[] array); ArrayList<Integer> returnAVector();
Strutture
Le strutture vengono tradotte in classi Java con un layout simile. Per esempio:
struct Bar { vec<bool> someBools; }; struct Foo { int32_t a; int8_t b; float[10] c; Bar d; };
… diventa:
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(); }
Tipi dichiarati
Ogni tipo di primo livello dichiarato in types.hal
ha il proprio file di output .java (come richiesto da Java). Ad esempio, il seguente file
types.hal
comporta la creazione di due file aggiuntivi (Foo.java
e Bar.java):
struct Foo { ... }; struct Bar { ... struct Baz { }; ... };
La definizione di Baz si trova in una classe interna statica di Bar (in Bar.java
).