The AIDL language is loosely based on the Java language. Files specify an interface contract and various data types and constants used in this contract.
Упаковка
Every AIDL files starts with an optional package that corresponds to the package names in various backends. A package declaration looks like this:
package my.package;
Similar to Java, AIDL files must be in a folder structure matching their package. Files with package my.package must be in the folder my/package/ .
Типы
In AIDL files, there are many places where types can be specified. For an exact list of types that are supported in the AIDL language, see AIDL backends types .
Аннотации
Several parts of the AIDL language support annotations. For a list of annotations and where they can be applied, see AIDL annotations .
Импорт
Для использования типов, определенных в других интерфейсах, необходимо сначала добавить зависимости в систему сборки. В модулях Soong cc_* и java_* , где файлы .aidl используются непосредственно в srcs в сборках платформы Android, вы можете добавить каталоги, используя поле aidl: { include_dirs: ... } . Инструкции по импорту с использованием aidl_interface см. здесь .
Импорт выглядит следующим образом:
import some.package.Foo; // explicit import
При импорте типа из того же пакета сам пакет можно опустить. Однако, отсутствие пакета может привести к неоднозначным ошибкам импорта, если типы указаны без пакета и помещены в глобальное пространство имен (как правило, все типы должны иметь пространство имен):
import Foo; // same as my.package.Foo
Define types
AIDL files generally define types which are used as an interface.
Интерфейсы
Вот пример интерфейса AIDL:
interface ITeleport {
// Location defined elsewhere
void teleport(Location baz, float speed);
String getName();
// ITeleportCallback defined elsewhere
void methodWithCallback(ITeleportCallback callback);
// ITeleportSession defined elsewhere
ITeleportSession getASubInterface();
}
Интерфейс определяет объект с набором методов. Методы могут быть oneway ( oneway void doFoo() ) или синхронными. Если интерфейс определен как oneway ( oneway interface ITeleport {...} ), то все методы в нем неявно являются oneway . Односторонние методы запускаются асинхронно и не могут возвращать результат. Односторонние методы из одного потока к одному и тому же связывателю также выполняются последовательно (хотя потенциально в разных потоках). Обсуждение настройки потоков см. в разделе «Управление потоками в бэкендах AIDL» .
Binder позволяет совместно использовать множество интерфейсов и объектов Binder через интерфейсы Binder. Интерфейсы AIDL часто используют коллбэки в рамках вызовов методов, как, например, ITeleportCallback в предыдущем примере. Вы можете повторно использовать объекты коллбэков между вызовами одного и того же метода или между вызовами разных методов. Еще одно распространенное использование типов интерфейсов — это возврат подинтерфейсов или объектов сессии из методов, как, например, ITeleportSession в предыдущем примере. Такая вложенность позволяет инкапсулировать различные API либо на уровне API, либо на основе состояния во время выполнения. Например, сессия может представлять собой владение определенным ресурсом. Когда интерфейсы передаются несколько раз или возвращаются клиенту или серверу, от которого они поступили, они всегда сохраняют равенство указателей базового объекта Binder.
Methods can have zero or more arguments. Arguments to methods can be in , out , or inout . For a discussion of how this affects arguments types, see AIDL backends directionality .
Посылки
For a description of how to create backend-specific parcelables, AIDL backends custom parcelables .
Android 10 и более поздние версии поддерживают определения парселируемых файлов непосредственно в AIDL. Этот тип парселируемого файла называется структурированным парселируемым файлом. Для получения дополнительной информации о взаимосвязи структурированного и стабильного AIDL в компиляторе AIDL и нашей системе сборки см. раздел «Структурированный и стабильный AIDL» .
Например:
package my.package;
import my.package.Boo;
parcelable Baz {
@utf8InCpp String name = "baz";
Boo boo;
}
Профсоюзы
Android 12 and higher support tagged union declarations. For example:
package my.package;
import my.package.FooSettings;
import my.package.BarSettings;
union Settings {
FooSettings fooSettings;
BarSettings barSettings;
@utf8InCpp String str;
int number;
}
See AIDL Backends Unions for backend-specific details.
Перечисления
Android 11 and higher support enum declarations. For example:
package my.package;
enum Boo {
A = 1 * 4,
B = 3,
}
Вложенные объявления типов
Android 13 and higher support nested type declarations. For example:
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
}
Константы
Custom AIDL interfaces, parcelables, and unions can also contain integer and string constants, such as:
const @utf8InCpp String HAPPY = ":)";
const String SAD = ":(";
const byte BYTE_ME = 1;
const int ANSWER = 6 * 7;
Постоянные выражения
Константы AIDL, размеры массивов и перечислители можно задавать с помощью константных выражений. Выражения могут использовать скобки для вложенности операций. Значения константных выражений могут использоваться как с целыми числами, так и с числами с плавающей запятой.
true and false literals represent boolean values. Values with a . but without a suffix, such as 3.8 , are considered to be double values. Float values have the f suffix, such as 2.4f . An integral value with the l or L suffix indicates a 64-bit long value. Otherwise, integrals values get the smallest value-preserving signed type between 8-bit (byte), 32-bit (int), and 64-bit (long). So 256 is considered to be an int , but 255 + 1 overflows to be the byte 0 . Hex values, such as 0x3 , are first interpreted as the smallest value-preserving unsigned type between 32-bit and 64-bit and then reinterpreted as unsigned values. So, 0xffffffff has the int value -1 . Starting in Android 13, the suffix u8 can be added to constants, such as 3u8 , to represent a byte value. This suffix is important so that a calculation, such as 0xffu8 * 3 , is interpreted as -3 with type byte whereas 0xff * 3 is 765 with type int .
Supported operators have C++ and Java semantics. In order from lowest to highest precedence, binary operators are || && | ^ & == != < > <= >= << >> + - * / % . Unary operators are + - ! ~ .