Język AIDL

Język AIDL jest luźno oparty na języku Java. Plik określa umowy interfejsu oraz różnych typów danych i stałych używanych w tej umowie.

Przesyłka

Każdy plik AIDL rozpoczyna się od opcjonalnego pakietu odpowiadającego pakietowi w różnych backendach. Deklaracja pakietu wygląda tak:

    package my.package;

Podobnie jak w przypadku Javy, pliki AIDL muszą mieć strukturę folderów pasującą do ich pakietu SDK. Pliki z pakietem my.package muszą znajdować się w folderze my/package/.

Typy

W plikach AIDL można określić wiele typów. Dokładną listę typów obsługiwanych w języku AIDL znajdziesz tutaj: Typy backendów AIDL.

Adnotacje

Niektóre fragmenty języka AIDL obsługują adnotacje. Lista: i sposobach ich stosowania, zobacz Adnotacje AIDL.

Importy

Aby użyć typów zdefiniowanych w innych interfejsach, musisz najpierw dodać zależności w systemu kompilacji. w modułach cc_* i java_*, w których używane są pliki .aidl. bezpośrednio w obszarze srcs w kompilacjach platformy Androida, możesz dodawać katalogi za pomocą pola aidl: { include_dirs: ... }. W przypadku importu przy użyciu aidl_interface, zobacz tutaj.

Proces importu wygląda tak:

    import some.package.Foo;  // explicit import

Podczas importowania typu do tego samego pakietu pakiet można pominąć. Mimo że Pominięcie pakietu może prowadzić do niejednoznacznych błędów importu, gdy typy określone bez pakietu i umieszczone w globalnej przestrzeni nazw (zwykle są to wszystkie typy powinna być przestrzenią nazw):

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

Zdefiniuj typy

Pliki AIDL zasadniczo definiują typy używane jako interfejsy.

Interfejsy

Oto przykładowy interfejs AIDL:

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

Interfejs definiuje obiekt za pomocą serii metod. Metody mogą być oneway (oneway void doFoo()) lub synchroniczne. Jeśli interfejs jest zdefiniowany jako oneway (oneway interface ITeleport {...}), wszystkie zawarte w niej metody domyślnie oneway. Metody jednokierunkowe są wysyłane asynchronicznie i nie mogą nie zwróci wyniku. Jednokierunkowe metody z tego samego wątku do tego samego separatora mogą być wykonywane szeregowo (choć potencjalnie w różnych wątkach). Dla dyskusji na temat konfigurowania wątków. Więcej informacji znajdziesz w wątku dotyczącym backendów AIDL. .

Metody mogą mieć zero lub więcej argumentów. Argumenty metod mogą być in, out lub inout. Aby dowiedzieć się, jak to wpływa na typy argumentów, zobacz Kierunkowość backendu AIDL.

Parcelables

Aby dowiedzieć się, jak tworzyć pakiety dodatkowe specyficzne dla backendu, Niestandardowe backendy AIDL Parcelables.

Android 10 i nowsze wersje obsługują definicje parlamentarne bezpośrednio w AIDL. Ten typ przesyłki nazywanej paczkomatem strukturalnym. Więcej informacji o tym, jak uporządkowane i stabilne AIDL są ze sobą powiązane, znajdziesz w Kompilator AIDL i nasz system kompilacji: Uporządkowane a stabilne AIDL.

Na przykład:

    package my.package;

    import my.package.Boo;

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

Związki

deklaracje dotyczące wsparcia dla Androida 12 i nowszych wersji. 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;
    }

Wykazy

Android 11 i nowsze wersje obsługują deklaracje typu enum. Na przykład:

    package my.package;

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

Deklaracje typu zagnieżdżonego

Android 13 i nowsze wersje obsługują deklaracje typu zagnieżdżone. 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, obiekty parcelable i sumy mogą też zawierać liczby całkowite i ciągi znaków, 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 elementy wyliczające można określić za pomocą stałej wyrażeń. W wyrażeniach możesz używać nawiasów do zagnieżdżania operacji. Stała wartości wyrażeń można używać z wartościami całkowitymi lub zmiennoprzecinkowymi.

Literale true i false reprezentują wartości logiczne. Wartości z parametrem . oprócz bez sufiksu, np. 3.8, są uznawane za wartości podwójne. Pływające wartości mają sufiks f, np. 2.4f. Wartość całkowita z parametrem l lub Sufiks L oznacza wartość o długości 64 bitów. W przeciwnym razie wartości całkowite otrzymują najmniejszy z zachowaniem wartości typu podpisany między 8-bitowym (bajtowym) i 32-bitowym (int), i 64-bitowej (długiej). Dlatego 256 uznaje się za int, ale 255 + 1 przepełnia się na byte 0. Wartości szesnastkowe, np. 0x3, są interpretowane w pierwszej kolejności. jako najmniejszy, zachowujący wartość typ bez znaku, między 32-bitowym a 64-bitowym. a potem zinterpretowany jako wartości bez znaku. Zatem 0xffffffff ma wartość int -1 Od Androida 13 sufiks u8 może mieć do wartości stałych, takich jak 3u8, w celu odzwierciedlenia wartości byte. Ten sufiks to jest ważne, aby obliczenia, takie jak 0xffu8 * 3, były interpretowane jako -3 z typem byte, a 0xff * 3 to 765 z typem int.

Obsługiwane operatory mają semantykę w językach C++ i Java. W kolejności od najniższej do najniższej o najwyższym priorytecie, operatory binarne są || && | ^ & == != < > <= >= << >> + - * / % Jednoargumentowe operatory to + - ! ~.