資料類型

在提供 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 新增對 memoryhandle 類型的支援。

由於 Java 執行階段並未原生支援未簽署整數的概念,因此所有未簽署類型 (以及以此為基礎的列舉) 都會在未知會用戶的情況下,視為已簽署的等效類型,也就是說,uint32_t 會在 Java 介面中變成 int。系統不會執行值轉換作業;Java 端的實作者必須將已簽署的值視為未簽署的值使用。

列舉

列舉不會產生 Java 列舉類別,而是會轉譯為內部類別,其中包含每個列舉情況的靜態常數定義。如果列舉類別衍生自其他列舉類別,則會繼承該類別的儲存類型。以未簽署整數類型為基礎的列舉會重寫為帶有簽名的等效值。由於基礎類型是原始類型,即使沒有零枚舉器,枚舉欄位/變數的預設值仍為零。

例如,類型為 uint8_tSomeBaseEnum

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 支援功能,可支援 handlememory 類型。分別轉譯為 android.os.NativeHandleandroid.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 中)。