数据类型

给定 HIDL 接口文件,Java HIDL 后端会生成 Java 接口、Stub 和代理代码。它支持所有标量 HIDL 类型([ u ] int { 8,16,32,64}_t, float, double,enum ),以及字符串、接口、safe_union 类型、结构类型以及受支持的数组和向量HIDL 类型。 Java HIDL 后端不支持联合类型或 fmq 类型。 Android 11 增加了对memoryhandle类型的支持。

由于 Java 运行时本身不支持无符号整数的概念,因此所有无符号类型(以及基于它们的枚举)都被默默地视为它们的有符号等价物,即uint32_t成为 Java 接口中的int 。不进行任何值转换; Java 端的实现者必须像使用无符号值一样使用有符号值。

枚举

枚举不会生成 Java 枚举类,而是转换为包含每个枚举情况的静态常量定义的内部类。如果枚举类派生自某个其他枚举类,它将继承该类的存储类型。基于无符号整数类型的枚举被重写为其有符号等价类型。由于基础类型是基元,因此即使没有零枚举器,枚举字段/变量的默认值也为零。

例如,类型为uint8_tSomeBaseEnum

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

弦乐

Java 中的String为 utf-8 或 utf-16,但在传输时会转换为 utf-8 作为常见的 HIDL 类型。此外,传递到 HIDL 时String不得为 null。

手柄和内存

Android 11 引入了对handlememory类型的 Java 支持。它们分别被翻译为android.os.NativeHandleandroid.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文件会导致创建两个额外文件(Foo.java 和 Bar.java):

struct Foo {
 ...
};

struct Bar {
 ...

 struct Baz {
 };

 ...
};

Baz 的定义位于 Bar 的静态内部类中(在 Bar.java 中)。