AIDL 语言大致上基于 Java 语言。文件会指定接口协定以及此协定中使用的各种数据类型和常量。
软件包
每个 AIDL 文件都以一个可选软件包开头,该软件包与各个后端中的软件包名称相对应。软件包声明如下所示:
package my.package;
与 Java 类似,AIDL 文件必须位于与其软件包匹配的文件夹结构中。包含软件包 my.package
的文件必须位于 my/package/
文件夹中。
类型
在 AIDL 文件中,可以在许多位置指定类型。如需查看 AIDL 语言所支持类型的确切列表,请参阅 AIDL 后端类型。
注释
AIDL 语言的多个部分均支持注解。如需查看注解列表以及可以应用它们的位置,请参阅 AIDL 注解。
导入
如需使用其他接口中定义的类型,必须先在构建系统中添加依赖项。在 cc_*
和 java_*
Soong 模块中,.aidl
文件会直接在 Android 平台 build 中的 srcs
下使用,您可以使用 aidl: { include_dirs: ... }
这一字段添加目录。如需使用 aidl_interface
导入,请参阅此处。
导入过程如下所示:
import some.package.Foo; // explicit import
导入同一软件包中的类型时,软件包可以省略。不过,如果在未指定软件包的情况下指定类型并放入全局命名空间(通常所有类型都应设定命名空间),则省略软件包可能会导致不明确的导入错误:
import Foo; // same as my.package.Foo
定义类型
AIDL 文件一般会定义用作接口的类型。
接口
以下是一个 AIDL 接口示例:
interface ITeleport {
void teleport(Location baz, float speed);
String getName();
}
接口通过一系列方法定义对象。方法可以是 oneway
(oneway void doFoo()
),也可以是同步方法。如果某个接口被定义为 oneway
(oneway interface ITeleport {...}
),则该接口中的所有方法都隐式地带上 oneway
。oneway 方法会异步调度,并且无法返回结果。同一线程到同一 binder 的单向方法也会按顺序执行(但可能会在不同线程上执行)。如需查看有关如何设置线程的讨论,请参阅 AIDL 后端线程管理。
方法可以有零个或多个参数。方法的参数可以是 in
、out
或 inout
。如需查看有关这会如何影响参数类型的讨论,请参阅 AIDL 后端方向性。
Parcelable
如需了解如何创建特定于后端的 Parcelable,请参阅 AIDL 后端自定义 Parcelable。
Android 10 及更高版本支持直接使用 AIDL 进行 Parcelable 定义。这种类型的 Parcelable 称为结构化 Parcelable。如需详细了解结构化 AIDL 和稳定的 AIDL 在 AIDL 编译器和我们的构建系统中的关系,请参阅结构化 AIDL 与稳定的 AIDL。
例如:
package my.package;
import my.package.Boo;
parcelable Baz {
@utf8InCpp String name = "baz";
Boo boo;
}
联合体
Android 12 及更高版本支持联合体声明。例如:
package my.package;
import my.package.FooSettings;
import my.package.BarSettings;
union Settings {
FooSettings fooSettings;
BarSettings barSettings;
@utf8InCpp String str;
int number;
}
枚举
Android 11 及更高版本支持枚举声明。例如:
package my.package;
enum Boo {
A = 1 * 4,
B = 3,
}
嵌套类型声明
Android 13 及更高版本支持嵌套类型声明。例如:
package my.package;
import my.package.Baz;
interface IFoo {
void doFoo(Baz.Nested nested); // defined in my/package/Baz.aidl
void doBar(Bar bar); // defined below
parcelable Bar { ... } // nested type definition
}
常量
自定义 AIDL 接口、Parcelable 和联合体还可以包含整数和字符串常量,例如:
const @utf8InCpp String HAPPY = ":)";
const String SAD = ":(";
const byte BYTE_ME = 1;
const int ANSWER = 6 * 7;
常量表达式
您可以使用常量表达式指定 AIDL 常量、数组大小和枚举器。表达式可以使用括号来嵌套运算。常量表达式值可与整数或浮点值搭配使用。
true
和 false
字面量表示布尔值。包含 .
但没有后缀的值(例如 3.8
)会被视为双精度值。浮点值具有 f
后缀,例如 2.4f
。以 l
或 L
为后缀的整数值表示 64 位长的值。否则,整数值会获得 8 位(字节)、32 位(整型)和 64 位(长整型)之间的最小值保留有符号类型。因此,256
被视为 int
,但 255 + 1
溢出为 byte
0
。十六进制值(例如 0x3
)首先被解析为 32 位到 64 位之间的最小值保留无符号类型,然后再重新解析为无符号值。因此,0xffffffff
的 int
值为 -1
。从 Android 13 开始,可以将后缀 u8
添加到常量中(例如 3u8
),以表示 byte
值。此后缀非常重要,因此 0xffu8 * 3
计算解释为 -3
(类型为 byte
),而 0xff * 3
解释为 765
(类型为 int
)。
支持的运算符具有 C++ 和 Java 语义。按照优先级从低到高的顺序,二元运算符为 || && | ^ & == != < > <= >= << >> + - * / %
,一元运算符为 + - ! ~
。