เมื่อได้รับไฟล์อินเทอร์เฟซ HIDL แล้ว แบ็กเอนด์ HIDL ของ Java จะสร้างอินเทอร์เฟซ Java, สตับ และโค้ดพร็อกซี โดยรองรับประเภท HIDL แบบสเกลาร์ทั้งหมด ([u
]int
{8,16,32,64}_t, float, double,
และ enum
) รวมถึงสตริง, อินเทอร์เฟซ, ประเภท safe_union, ประเภท struct, อาร์เรย์ และเวกเตอร์ของประเภท HIDL ที่รองรับ แบ็กเอนด์ HIDL ของ Javaไม่รองรับประเภท Union หรือประเภท FMQ Android 11 เพิ่มการรองรับประเภท memory
และ handle
เนื่องจากรันไทม์ Java ไม่รองรับแนวคิดของจำนวนเต็มแบบไม่ลงนามโดยค่าเริ่มต้น ระบบจะถือว่าประเภทแบบไม่ลงนามทั้งหมด (และลิสต์แบบจำกัดที่อิงตามประเภทดังกล่าว) เป็นประเภทแบบลงนามที่เทียบเท่าโดยปริยาย เช่น uint32_t
จะกลายเป็น int
ในอินเทอร์เฟซ Java ระบบจะไม่แปลงค่า ผู้ใช้งานฝั่ง Java ต้องใช้ค่าที่มีเครื่องหมายเหมือนกับว่าไม่มีเครื่องหมาย
Enums
เอ็นทิตีจะไม่สร้างคลาสเอ็นทิตี Java แต่ระบบจะแปลเป็นคลาสภายในที่มีคําจํากัดความค่าคงที่แบบคงที่สําหรับแต่ละกรณีของเอ็นทิตี หากคลาส enum มาจากคลาส 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
ต้องไม่มีค่าเป็น Null เมื่อส่งไปยัง HIDL
แฮนเดิลและหน่วยความจํา
Android 11 รองรับ Java สำหรับประเภท handle
และ memory
โดยระบบจะแปลเป็น android.os.NativeHandle
และ android.os.HidlMemory
ตามลำดับ ระบบถือว่าแฮนเดิล Null ถูกต้อง แต่ความทรงจำ Null ถือว่าไม่ถูกต้อง
ในโค้ดเซิร์ฟเวอร์ที่สร้างขึ้น อาร์กิวเมนต์หน่วยความจำและตัวแฮนเดิลที่ได้รับจะใช้งานได้ภายในขอบเขตของการเรียกใช้เมธอดเท่านั้น หากการติดตั้งใช้งานเซิร์ฟเวอร์ต้องการขยายอายุการใช้งาน จะต้องทําซ้ำโดยใช้วิธีการ dup()
ที่เกี่ยวข้อง อินสแตนซ์ที่แสดงผลจะใช้งานได้หลังจากการเรียกใช้เมธอด และควรปิดอย่างถูกต้องเมื่อใช้งานเสร็จแล้ว
ในโค้ด client ที่สร้างขึ้น ตัวแฮนเดิลและอินสแตนซ์หน่วยความจำที่ส่งเป็นอาร์กิวเมนต์อินพุตของเมธอดที่เรียกใช้ไม่จำเป็นต้องทำซ้ำหรือเก็บไว้ให้ถูกต้องหลังจากเมธอดแสดงผลแล้ว อย่างไรก็ตาม ตัวแฮนเดิลและอินสแตนซ์หน่วยความจำที่ได้รับเป็นอาร์กิวเมนต์เอาต์พุตจะได้รับการทําซ้ำโดยอัตโนมัติโดยโค้ดที่สร้างขึ้นโดยอัตโนมัติ และต้องปิดอย่างถูกต้องเมื่อใช้งานเสร็จแล้ว ไม่ว่าจะปรากฏเป็นอาร์กิวเมนต์ที่แสดงผลของเมธอด (ในกรณีที่แสดงผลค่าเดียว) หรือใช้รูปแบบการเรียกกลับแบบซิงค์ (ใช้ในกรณีที่แสดงผลหลายค่า) ก็ตาม
ดูข้อมูลเพิ่มเติมเกี่ยวกับการทำซ้ำและการปิดได้ที่เอกสารประกอบของคลาส 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
)