Язык AIDL частично основан на языке Java. Файлы определяют контракт интерфейса и различные типы данных и константы, используемые в этом контракте.
Упаковка
Каждый файл AIDL начинается с необязательного пакета, который соответствует именам пакетов в различных бэкендах. Объявление пакета выглядит так:
package my.package;
Подобно Java, файлы AIDL должны находиться в структуре папок, соответствующей их пакету. Файлы с пакетом my.package
должны находиться в папке my/package/
.
Типы
В файлах AIDL есть много мест, где можно указать типы. Точный список типов, поддерживаемых в языке AIDL, см. в разделе Типы бэкэндов AIDL .
Аннотации
Несколько частей языка AIDL поддерживают аннотации. Список аннотаций и места их применения см. в Аннотации AIDL .
Импорт
Чтобы использовать типы, определенные в других интерфейсах, вы должны сначала добавить зависимости в систему сборки. В cc_*
и java_*
Soong, где файлы .aidl
используются непосредственно в srcs
в сборках платформы Android, вы можете добавлять каталоги, используя поле 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
. Односторонние методы отправляются асинхронно и не могут возвращать результат. Однонаправленные методы из одного и того же потока в один и тот же связыватель также гарантированно выполняются последовательно (хотя и потенциально в разных потоках). Обсуждение того, как настраивать потоки, см. в разделе Управление потоками бэкенда AIDL .
Методы могут иметь ноль или более аргументов. Аргументы методов могут быть in
, out
или inout
. Обсуждение того, как это влияет на типы аргументов, см. в разделе Направленность бэкэндов AIDL .
Parcelables
Для описания того, как создавать специфичные для бэкенда посылки, AIDL поддерживает пользовательские посылки .
Android 10 и более поздние версии поддерживают разделяемые декларации непосредственно в 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 и выше поддерживают объявления enum. Например:
package my.package;
enum Boo {
A = 1 * 4,
B = 3,
}
Объявления вложенных типов
Android T (экспериментальная версия AOSP) и более поздние версии поддерживают объявления вложенных типов. Например:
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, парцеллы и объединения также могут содержать целочисленные и строковые константы, такие как:
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-битным (byte), 32-битным (int) и 64-битным (long). Таким образом, 256
считается int
, но 255 + 1
переполняется как byte
0
. Шестнадцатеричные значения, такие как 0x3
, сначала интерпретируются как наименьший сохраняющий значение беззнаковый тип между 32-битным и 64-битным, а затем повторно интерпретируются как беззнаковые значения. Итак, 0xffffffff
имеет значение int
-1
. Начиная с Android T (экспериментальная версия AOSP) суффикс u8
может добавляться к константам, таким как 3u8
, для представления значения byte
. Этот суффикс важен, так как вычисление, такое как 0xffu8 * 3
, интерпретируется как -3
с типом byte
, тогда как 0xff * 3
равно 765
с типом int
.
Поддерживаемые операторы имеют семантику C++ и Java. В порядке от низшего к высшему приоритету бинарные операторы || && | ^ & == != < > <= >= << >> + - * / %
. Унарные операторы + - ! ~
.