給定一個 HIDL 接口文件,Java HIDL 後端會生成 Java 接口、存根和代理代碼。它支持所有標量 HIDL 類型([ u
] int
{ 8,16,32,64}_t, float, double,
和enum
s),以及支持的字符串、接口、safe_union 類型、結構類型以及數組和向量HIDL 類型。 Java HIDL 後端不支持聯合類型或 fmq 類型。 Android 11 增加了對memory
和handle
類型的支持。
由於 Java 運行時本身不支持無符號整數的概念,所有無符號類型(以及基於它們的枚舉)都被默默地視為它們的有符號等價物,即uint32_t
在 Java 接口中變為int
。不進行價值轉換; Java 端的實現者必須像使用無符號一樣使用帶符號的值。
枚舉
枚舉不生成 Java 枚舉類,而是轉換為內部類,其中包含每個枚舉案例的靜態常量定義。如果枚舉類派生自某個其他枚舉類,它會繼承該類的存儲類型。基於無符號整數類型的枚舉被重寫為它們的有符號等價物。由於基礎類型是原始類型,因此枚舉字段/變量的默認值為零,即使沒有零枚舉數也是如此。
例如,類型為uint8_t
的SomeBaseEnum
:
enum SomeBaseEnum : uint8_t { foo = 3 }; enum SomeEnum : SomeBaseEnum { quux = 33, goober = 127 };
……變成:
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; }
和:
enum SomeEnum : uint8_t { FIRST_CASE = 10, SECOND_CASE = 192 };
……改寫為:
public final class SomeEnum { static public final byte FIRST_CASE = 10; // no change static public final byte SECOND_CASE = -64; }
字符串
Java 中的String
是 utf-8 或 utf-16 但在傳輸時會轉換為 utf-8 作為常見的 HIDL 類型。此外, String
在傳遞到 HIDL 時不得為空。
手柄和內存
Android 11 引入了對handle
和memory
類型的 Java 支持。它們分別被翻譯成android.os.NativeHandle
和android.os.HidlMemory
。空句柄被認為是有效的,而空內存則不是。
在生成的服務器代碼中,接收到的內存和句柄參數僅在方法調用的範圍內有效。如果服務器實現想要延長它們的生命週期,則必須使用它們各自的dup()
方法來複製它們。返回的實例可以在方法調用之外使用,完成後應該正確關閉。
在生成的客戶端代碼中,作為被調用方法的輸入參數發送的句柄和內存實例不需要在方法返回後重複或保持有效。但是,作為輸出參數接收的句柄和內存實例會被自動生成的代碼自動複製,並且在完成後必須正確關閉。無論這些返回參數顯示為方法的返回值(在單個返回值情況下)還是使用同步回調樣式(在多個返回值情況下使用),都是如此。
有關複製和關閉的更多信息,請參閱 Java 類的文檔。
數組和向量
數組被轉換為 Java 數組,向量被轉換為ArrayList<T>
,其中 T 是適當的對像類型,可能包含標量類型,例如vec<int32_t> => ArrayList<Integer>
)。例如:
takeAnArray(int32_t[3] array); returnAVector() generates (vec<int32_t> result);
……變成:
void takeAnArray(int[] array); ArrayList<Integer> returnAVector();
結構
結構被翻譯成具有類似佈局的 Java 類。例如:
struct Bar { vec<bool> someBools; }; struct Foo { int32_t a; int8_t b; float[10] c; Bar d; };
……變成:
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(); }
聲明的類型
在types.hal
中聲明的每個頂級類型都有自己的 .java 輸出文件(根據 Java 的要求)。例如,以下types.hal
文件會導致創建兩個額外的文件(Foo.java 和 Bar.java):
struct Foo { ... }; struct Bar { ... struct Baz { }; ... };
Baz 的定義存在於 Bar 的靜態內部類中(在 Bar.java 中)。