給定 HIDL 介面文件,Java HIDL 後端會產生 Java 介面、Stub 和代理程式碼。它支援所有標量 HIDL 類型([ u
] int
{ 8,16,32,64}_t, float, double,
和enum
),以及字串、介面、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 類型。此外,傳遞到 HIDL 時String
不得為 null。
手把和內存
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 中)。