在提供 HIDL 介面檔案的情況下,Java HIDL 後端會產生 Java 介面、Stub 和 Proxy 程式碼。它支援所有標量 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
不得為空值。
句柄和記憶體
Android 11 推出 Java 支援功能,可支援 handle
和 memory
類型。分別轉譯為 android.os.NativeHandle
和 android.os.HidlMemory
。空值句柄視為有效,而空值記憶體則不視為有效。
在產生的 server 程式碼中,收到的記憶體和句柄引數僅在方法叫用範圍內有效。如果伺服器實作項目想要延長其生命週期,則必須使用各自的 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
中)。