Với một tệp giao diện HIDL, phần phụ trợ HIDL Java sẽ tạo ra các giao diện Java, Stub và mã Proxy. Nó hỗ trợ tất cả các loại HIDL vô hướng ([u
]int
{8,16,32,64}_t, float, double,
và enum
s), cũng như các chuỗi, giao diện, loại safe_union, loại struct, mảng và vectơ của các loại HIDL được hỗ trợ. Phần phụ trợ HIDL Java KHÔNG hỗ trợ các loại hợp nhất hoặc các loại fmq. Android 11 bổ sung tính năng hỗ trợ cho các loại memory
và handle
.
Vì thời gian chạy Java không hỗ trợ khái niệm về số nguyên không dấu một cách tự nhiên, nên tất cả các loại không dấu (và các enum dựa trên các loại đó) đều được coi là các loại có dấu tương đương, tức là uint32_t
sẽ trở thành int
trong giao diện Java. Không có lượt chuyển đổi giá trị nào được thực hiện; người triển khai ở phía Java phải sử dụng các giá trị đã ký như thể chúng chưa được ký.
Liệt kê
Các enum không tạo ra các lớp enum Java mà thay vào đó được dịch thành các lớp bên trong chứa một định nghĩa hằng số tĩnh cho mỗi trường hợp enum. Nếu lớp liệt kê bắt nguồn từ một lớp liệt kê khác, thì lớp đó sẽ kế thừa loại lưu trữ của lớp đó. Các kiểu liệt kê dựa trên kiểu số nguyên không dấu sẽ được viết lại thành kiểu tương đương có dấu. Vì kiểu cơ bản là kiểu nguyên thuỷ, nên giá trị mặc định cho các trường/biến enum là 0 ngay cả khi không có số liệt kê 0.
Ví dụ: SomeBaseEnum
có loại uint8_t
:
enum SomeBaseEnum : uint8_t { foo = 3 }; enum SomeEnum : SomeBaseEnum { quux = 33, goober = 127 };
… trở thành:
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; }
Và:
enum SomeEnum : uint8_t { FIRST_CASE = 10, SECOND_CASE = 192 };
… được viết lại thành:
public final class SomeEnum { static public final byte FIRST_CASE = 10; // no change static public final byte SECOND_CASE = -64; }
Chuỗi
String
trong Java là utf-8 hoặc utf-16 nhưng được chuyển đổi thành utf-8 làm loại HIDL phổ biến khi được truyền. Ngoài ra, String
không được có giá trị rỗng khi được truyền vào HIDL.
Tay cầm và bộ nhớ
Android 11 giới thiệu khả năng hỗ trợ Java cho các loại handle
và memory
. Chúng được dịch thành android.os.NativeHandle
và android.os.HidlMemory
tương ứng. Một giá trị nhận dạng rỗng được coi là hợp lệ, trong khi một bộ nhớ rỗng thì không.
Trong mã máy chủ đã tạo, bộ nhớ đã nhận và các đối số xử lý chỉ hợp lệ trong phạm vi lệnh gọi phương thức. Nếu muốn kéo dài thời gian tồn tại, thì quá trình triển khai máy chủ phải được sao chép bằng các phương thức dup()
tương ứng. Bạn có thể sử dụng thực thể được trả về ngoài lệnh gọi phương thức và phải đóng đúng cách khi hoàn tất.
Trong mã client đã tạo, các đối tượng xử lý và thực thể bộ nhớ được gửi dưới dạng đối số đầu vào của phương thức được gọi không cần phải được sao chép cũng như duy trì trạng thái hợp lệ sau khi phương thức trả về. Tuy nhiên, các đối tượng xử lý và phiên bản bộ nhớ nhận dưới dạng đối số đầu ra sẽ được mã tự động tạo sao chép tự động và phải được đóng đúng cách khi hoàn tất. Điều này đúng cho dù các đối số trả về đó xuất hiện dưới dạng giá trị trả về của phương thức (trong trường hợp có một giá trị trả về) hay sử dụng kiểu gọi lại đồng bộ (được dùng trong trường hợp có nhiều giá trị trả về).
Để biết thêm thông tin về việc sao chép và đóng, hãy xem tài liệu về các lớp Java.
Mảng và vectơ
Mảng được dịch thành mảng Java và vectơ được dịch thành ArrayList<T>
, trong đó T là loại đối tượng thích hợp, có thể bao bọc các loại vô hướng như vec<int32_t> =>
ArrayList<Integer>
). Ví dụ:
takeAnArray(int32_t[3] array); returnAVector() generates (vec<int32_t> result);
… trở thành:
void takeAnArray(int[] array); ArrayList<Integer> returnAVector();
Cấu trúc
Các cấu trúc được dịch thành các lớp Java có bố cục tương tự. Ví dụ:
struct Bar { vec<bool> someBools; }; struct Foo { int32_t a; int8_t b; float[10] c; Bar d; };
… trở thành:
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(); }
Các loại được khai báo
Mỗi loại cấp cao nhất được khai báo trong types.hal
sẽ có tệp đầu ra .java riêng (theo yêu cầu của Java). Ví dụ: tệp types.hal
sau đây sẽ tạo ra 2 tệp bổ sung (Foo.java và Bar.java):
struct Foo { ... }; struct Bar { ... struct Baz { }; ... };
Định nghĩa của Baz nằm trong một lớp tĩnh bên trong của Bar (trong Bar.java
).