ประเภทข้อมูล

เมื่อได้รับไฟล์อินเทอร์เฟซ HIDL แบ็กเอนด์ HIDL ของ Java จะสร้างอินเทอร์เฟซ Java, Stub และโค้ดพร็อกซี รองรับ HIDL ประเภทสเกลาร์ทั้งหมด ([u]int{8,16,32,64}_t, float, double, และ enums) รวมถึงสตริง อินเทอร์เฟซ ประเภท safe_union, ประเภท struct และอาร์เรย์และเวกเตอร์ของประเภท HIDL ที่รองรับ แบ็กเอนด์ HIDL ของ Java ไม่รองรับประเภทสหภาพหรือประเภท FMQ Android 11 เพิ่มการรองรับประเภท memory และ handle

เนื่องจากรันไทม์ Java ไม่รองรับแนวคิดของจำนวนเต็มที่ไม่มีเครื่องหมายโดยกำเนิด ระบบจึงถือว่าประเภทที่ไม่มีเครื่องหมายทั้งหมด (และ Enum ที่อิงตามประเภทเหล่านั้น) เป็นประเภทที่มีเครื่องหมายที่เทียบเท่า กล่าวคือ uint32_t จะกลายเป็น int ใน อินเทอร์เฟซ Java ไม่มีการแปลงค่าใดๆ ผู้ใช้ที่ติดตั้งใช้งานในฝั่ง Java ต้องใช้ค่าที่ลงนามแล้วราวกับว่าค่าเหล่านั้นไม่ได้ลงนาม

Enums

Enums จะไม่สร้างคลาส enum ของ Java แต่จะแปลเป็นคลาสภายในแทน ซึ่งมีคำจำกัดความค่าคงที่แบบคงที่สำหรับแต่ละกรณีของ enum หาก enum class สืบทอดมาจากคลาส enum อื่น ระบบจะสืบทอดประเภทพื้นที่เก็บข้อมูลของคลาสนั้น ระบบจะเขียนการแจงนับตามประเภทจำนวนเต็มที่ไม่มีเครื่องหมายใหม่เป็นจำนวนเต็มที่มีเครื่องหมาย ที่เทียบเท่า เนื่องจากประเภทพื้นฐานเป็นแบบดั้งเดิม ค่าเริ่มต้นสำหรับ ฟิลด์/ตัวแปร enum จึงเป็น 0 แม้ว่าจะไม่มีตัวแจงนับ 0 ก็ตาม

เช่น SomeBaseEnum ที่มีประเภทเป็น uint8_t

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;
}

เครื่องสาย

String ใน Java คือ utf-8 หรือ utf-16 แต่จะแปลงเป็น utf-8 เป็นประเภท HIDL ทั่วไปเมื่อมีการส่ง นอกจากนี้ String ต้องไม่เป็นค่าว่างเมื่อส่งไปยัง HIDL

แฮนเดิลและหน่วยความจำ

Android 11 เปิดตัวการรองรับ Java สำหรับประเภท handle และ memory โดยจะแปลเป็นภาษา 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 ต่อไปนี้จะทำให้มีการสร้างไฟล์เพิ่มเติม 2 ไฟล์ (Foo.java และ Bar.java)

struct Foo {
 ...
};

struct Bar {
 ...

 struct Baz {
 };

 ...
};

คำจำกัดความของ Baz อยู่ในคลาสภายในแบบคงที่ของ Bar (ใน Bar.java)