เมื่อได้รับไฟล์อินเทอร์เฟซ HIDL แบ็กเอนด์ HIDL ของ Java จะสร้างอินเทอร์เฟซ Java,
Stub และโค้ดพร็อกซี รองรับ HIDL ประเภทสเกลาร์ทั้งหมด
([u
]int
{8,16,32,64}_t, float, double,
และ
enum
s) รวมถึงสตริง อินเทอร์เฟซ ประเภท 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
)