Język AIDL

Język AIDL jest luźno oparty na języku Java. Pliki określają kontrakt interfejsu oraz różne typy danych i stałe używane w tym kontrakcie.

Pakiet

Każdy plik AIDL zaczyna się od opcjonalnego pakietu, który odpowiada nazwom pakietów w różnych backendach. Deklaracja pakietu wygląda następująco:

    package my.package;

Podobnie jak w Javie, pliki AIDL muszą znajdować się w strukturze folderów odpowiadającej ich pakietowi. Pliki z pakietem my.package muszą znajdować się w folderze my/package/ .

Typy

W plikach AIDL jest wiele miejsc, w których można określić typy. Aby uzyskać dokładną listę typów obsługiwanych w języku AIDL, zobacz Typy zaplecza AIDL .

Adnotacje

Kilka części adnotacji obsługujących język AIDL. Aby zapoznać się z listą adnotacji i miejsca ich zastosowania, zobacz Adnotacje AIDL .

Import

Aby użyć typów zdefiniowanych w innych interfejsach, należy najpierw dodać zależności w systemie kompilacji. W modułach cc_* i java_* Soong, gdzie pliki .aidl są używane bezpośrednio w srcs w kompilacjach platformy Android, możesz dodawać katalogi za pomocą pola aidl: { include_dirs: ... } . Informacje na temat importu przy użyciu aidl_interface można znaleźć tutaj .

Import wygląda następująco:

    import some.package.Foo;  // explicit import

Podczas importowania typu w tym samym pakiecie pakiet można pominąć. Chociaż pominięcie pakietu może prowadzić do niejednoznacznych błędów importu, gdy typy są określone bez pakietu i umieszczone w globalnej przestrzeni nazw (zazwyczaj wszystkie typy powinny mieć przestrzeń nazw):

    import Foo;  // same as my.package.Foo

Definiowanie typów

Pliki AIDL ogólnie definiują typy używane jako interfejs.

Interfejsy

Oto przykładowy interfejs AIDL:

    interface ITeleport {
        void teleport(Location baz, float speed);
        String getName();
    }

Interfejs definiuje obiekt za pomocą szeregu metod. Metody mogą być oneway ( oneway void doFoo() ) lub synchroniczne. Jeśli interfejs jest zdefiniowany jako oneway ( oneway interface ITeleport {...} ), wówczas wszystkie zawarte w nim metody są domyślnie oneway . Metody jednokierunkowe są wywoływane asynchronicznie i nie mogą zwrócić wyniku. Gwarantuje się również, że metody jednokierunkowe z tego samego wątku do tego samego spoiwa będą wykonywane szeregowo (chociaż potencjalnie w różnych wątkach). Aby zapoznać się z omówieniem konfigurowania wątków, zobacz Zarządzanie wątkami zaplecza AIDL .

Metody mogą mieć zero lub więcej argumentów. Argumenty metod mogą być in , out lub inout . Aby zapoznać się z omówieniem wpływu tego na typy argumentów, zobacz Kierunkowość zaplecza AIDL .

Przesyłki

Aby uzyskać opis sposobu tworzenia pakietów specyficznych dla backendu, AIDL backends niestandardowych pakietów paczkowych .

Android 10 i nowsze obsługują definicje umożliwiające pakowanie bezpośrednio w AIDL. Ten rodzaj przesyłek paczkowanych nazywa się przesyłkami strukturalnymi. Aby uzyskać więcej informacji na temat powiązań strukturalnego i stabilnego AIDL w kompilatorze AIDL i naszym systemie kompilacji, zobacz Strukturalny i stabilny AIDL .

Na przykład:

    package my.package;

    import my.package.Boo;

    parcelable Baz {
        @utf8InCpp String name = "baz";
        Boo boo;
    }

Związki

Android 12 i nowsze obsługują deklaracje unii. Na przykład:

    package my.package;

    import my.package.FooSettings;
    import my.package.BarSettings;

    union Settings {
        FooSettings fooSettings;
        BarSettings barSettings;
        @utf8InCpp String str;
        int number;
    }

Wyliczenia

Deklaracje wyliczeń obsługujące Androida 11 i nowsze. Na przykład:

    package my.package;

    enum Boo {
        A = 1 * 4,
        B = 3,
    }

Deklaracje typów zagnieżdżonych

Android 13 i nowsze obsługują deklaracje typów zagnieżdżonych. Na przykład:

    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
    }

Stałe

Niestandardowe interfejsy AIDL, pakiety i unie mogą również zawierać stałe całkowite i łańcuchowe, takie jak:

    const @utf8InCpp String HAPPY = ":)";
    const String SAD = ":(";
    const byte BYTE_ME = 1;
    const int ANSWER = 6 * 7;

Wyrażenia stałe

Stałe AIDL, rozmiary tablic i moduły wyliczające można określić za pomocą wyrażeń stałych. W wyrażeniach można używać nawiasów do zagnieżdżania operacji. Wartości wyrażeń stałych można używać z wartościami całkowitymi lub zmiennoprzecinkowymi.

literały true i false reprezentują wartości logiczne. Wartości z . ale bez przyrostka, takiego jak 3.8 , są uważane za wartości podwójne. Wartości zmiennoprzecinkowe mają przyrostek f , na przykład 2.4f . Wartość całkowita z przyrostkiem l lub L oznacza wartość o długości 64 bitów. W przeciwnym razie wartości całkowe uzyskują najmniejszy typ znaku zachowujący wartość między 8-bitowym (bajtem), 32-bitowym (int) i 64-bitowym (długim). Zatem 256 jest uważane za int , ale 255 + 1 przepełnia się jako byte 0 . Wartości szesnastkowe, takie jak 0x3 , są najpierw interpretowane jako najmniejszy typ bez znaku zachowujący wartość między 32-bitowymi a 64-bitowymi, a następnie ponownie interpretowane jako wartości bez znaku. Zatem 0xffffffff ma wartość int -1 . Począwszy od Androida 13, do stałych, takich jak 3u8 , można dodać przyrostek u8 , aby reprezentować wartość byte . Ten przyrostek jest ważny, ponieważ obliczenia takie jak 0xffu8 * 3 są interpretowane jako -3 w przypadku typu byte , podczas gdy 0xff * 3 wynosi 765 w przypadku typu int .

Obsługiwane operatory mają semantykę C++ i Java. W kolejności od najniższego do najwyższego priorytetu operatorami binarnymi są || && | ^ & == != < > <= >= << >> + - * / % . Operatory jednoargumentowe to + - ! ~ .