Kiểu dữ liệu

Với một tệp giao diện HIDL, phần phụ trợ HIDL của Java sẽ tạo các giao diện Java, mã Stub và Proxy. Công cụ này hỗ trợ tất cả các loại HIDL vô hướng ([u]int{8,16,32,64}_t, float, double,enums), cũng như các chuỗi, giao diện, loại safe_union, loại cấu trúc và các 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 liên kết hoặc loại fmq. Android 11 thêm tính năng hỗ trợ cho các loại memoryhandle.

Vì môi trường thời gian chạy Java không hỗ trợ khái niệm số nguyên không dấu gốc, nên tất cả các loại không dấu (và enum dựa trên các loại đó) đều được xử lý ngầm như các loại tương đương đã ký, tức là uint32_t trở thành int trong giao diện Java. Không thực hiện chuyển đổi giá trị; trình triển khai ở bên Java phải sử dụng các giá trị đã ký như thể chúng chưa được ký.

Liệt kê

Enum không tạo các lớp enum Java mà thay vào đó được dịch thành các lớp bên trong chứa định nghĩa hằng số tĩnh cho mỗi trường hợp enum. Nếu lớp enum bắt nguồn từ một số lớp enum khác, thì lớp đó sẽ kế thừa loại bộ nhớ của lớp đó. Các enum dựa trên loại số nguyên chưa ký được viết lại thành số nguyên đã ký tương đương. Vì loại cơ bản là loại gốc, nên giá trị mặc định cho các trường/biến enum là 0 ngay cả khi không có bộ đếm số 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 như sau:

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 dưới dạng loại HIDL phổ biến khi được truyền. Ngoài ra, String không được để trống khi được truyền vào HIDL.

Tay cầm và bộ nhớ

Android 11 giới thiệu tính năng hỗ trợ Java cho các loại handlememory. Các giá trị này được dịch thành android.os.NativeHandleandroid.os.HidlMemory tương ứng. Một tay cầm rỗng được coi là hợp lệ, trong khi bộ nhớ rỗng thì không.

Trong mã máy chủ được tạo, bộ nhớ đã nhận và đối số xử lý chỉ hợp lệ trong phạm vi lệnh gọi phương thức. Nếu quá trình triển khai máy chủ muốn kéo dài thời gian hoạt động, thì các phiên bản này 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ã ứng dụng được tạo, các thực thể bộ nhớ và tay điều khiển đượ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ư không cần phải giữ nguyên trạng thái hợp lệ sau khi phương thức trả về. Tuy nhiên, các thực thể bộ nhớ và tay điều khiển được nhận dưới dạng đối số đầu ra sẽ tự động được sao chép bởi mã được tạo 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 giá trị trả về duy nhất) hay sử dụng kiểu gọi lại đồng bộ (dùng trong trường hợp 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 sang mảng Java và vectơ được dịch sang ArrayList<T>, trong đó T là loại đối tượng thích hợp, có thể gói các loại vectơ 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 sang 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();
}

Loại đã khai báo

Mỗi loại cấp cao nhất được khai báo trong types.hal sẽ nhận đượ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 thêm 2 tệp (Foo.java và Bar.java):

struct Foo {
 ...
};

struct Bar {
 ...

 struct Baz {
 };

 ...
};

Phần khai báo của Baz nằm trong một lớp bên trong tĩnh của Bar (trong Bar.java).