Adnotacje w AIDL

AIDL obsługuje adnotacje, które przekazują kompilatorowi AIDL dodatkowe informacje na temat elementu z adnotacjami, co również wpływa na wygenerowany kod pośredni.

Składnia jest podobna do składni w Javie:

@AnnotationName(argument1=value, argument2=value) AidlEntity

AnnotationName to nazwa adnotacji, a AidlEntity to encję AIDL, taką jak interface Foo, void method() lub int arg. An jest dołączona do następującej po niej jednostki.

Niektóre adnotacje mogą mieć argumenty umieszczone w nawiasach, jak pokazano powyżej. Adnotacje, które nie mają argumentu, nie wymagają nawiasów. Na przykład:

@AnnotationName AidlEntity

Te adnotacje różnią się od tych w Javie chociaż są one bardzo podobne. Użytkownicy nie mogą definiować niestandardowego identyfikatora AIDL adnotacje; Wszystkie adnotacje są wstępnie zdefiniowane. Niektóre adnotacje wpływają tylko na tylko w określonym backendzie, a w innych nie działają. Różnią się ograniczeń, do których można je dołączyć.

Oto lista wstępnie zdefiniowanych adnotacji AIDL:

Adnotacje Dodano w wersji Androida
nullable 7
utf8InCpp 7
VintfStability 11
UnsupportedAppUsage 10
Hide 11
Backing 11
NdkOnlyStableParcelable 14
JavaOnlyStableParcelable 11
JavaDerive 12
JavaPassthrough 12
FixedSize 12
Descriptor 12

dopuszczalna wartość null

nullable deklaruje, że nie można podać wartości elementu z adnotacjami.

Tę adnotację można dołączyć tylko do zwracanych typów metod, parametrów metod i pola działki.

interface IFoo {
    // method return types
    @nullable Data method();

    // method parameters
    void method2(in @nullable Data d);
}

parcelable Data {
    // parcelable fields
    @nullable Data d;
}

Adnotacji nie można dołączać do typów podstawowych. Ten błąd.

void method(in @nullable int a); // int is a primitive type

Ta adnotacja nie działa w backendzie Java. To dlatego, że w Javie wszystkie typy inne niż podstawowe są przekazywane przez odwołanie, którym może być wartość null.

W backendzie CPP interfejs @nullable T jest mapowany na std::unique_ptr<T> w Androidzie 11 lub niższy i std::optional<T> na Androidzie 12 lub więcej.

W backendzie NDK wartość @nullable T zawsze jest mapowana na std::optional<T>.

W przypadku typu listy L, takiego jak T[] lub List<T>, wartość @nullable L jest mapowana na std::optional<std::vector<std::optional<T>>> (lub std::unique_ptr<std::vector<std::unique_ptr<T>>> w przypadku backendu CPP na Androida 11 lub starszego).

Występuje wyjątek od tego mapowania. Gdy T to IBinder lub interfejs AIDL, @nullable jest no-op. Inaczej mówiąc, zarówno @nullable IBinder i IBinder są mapowane w równym stopniu na android::sp<IBinder>, która ma już wartość null, ponieważ jest to silny wskaźnik (CPP odczytuje wymuszać dodawanie wartości null, ale typ to nadal android::sp<IBinder>).

Począwszy od Androida 13, aplikacji @nullable(heap=true) można używać do: do modelowania typów rekurencyjnych. Nie można użyć karty @nullable(heap=true) za pomocą parametrów metody lub typów zwracanych. Gdy zostanie opatrzona adnotacjami, zmapowano na odwołanie std::unique_ptr<T> przypisane do stosu w CPP/NDK z backendami. Interfejs @nullable(heap=true) nie działa w backendzie Java.

UTf8InCpp

utf8InCpp deklaruje, że plik String jest prezentowany w formacie UTF8 dla CPP z backendem. Jak sama nazwa wskazuje, adnotacja nie jest operacją w innych backendach. Konkretnie, String to zawsze kodowanie UTF16 w backendzie Javy i UTF8 w NDK. z backendem.

Tę adnotację można dołączyć wszędzie tam, gdzie można użyć typu String, w tym zwracane wartości, parametry, deklaracje stałe i parcelable. .

W backendzie CPP wartość @utf8InCpp String w AIDL jest mapowana na std::string, podczas gdy String bez adnotacji mapuje na android::String16, gdzie jest używany kod UTF16.

Pamiętaj, że adnotacja utf8InCpp nie zmienia sposobu są przesyłane przez przewód. Ciągi znaków są zawsze przesyłane w formacie UTF16 ponad przewód. Ciąg znaków z adnotacjami utf8InCpp jest konwertowany na UTF16 przed przesyłane. Po odebraniu ciągu znaków zostaje on zmieniony z UTF16 na UTF8, jeśli został oznaczony adnotacją utf8InCpp.

Stabilność Vintf

VintfStability deklaruje, że typ zdefiniowany przez użytkownika (interfejs, parcelable, i enum) mogą być używane w domenach systemu i dostawców. Zobacz AIDL dla klientów HAL, aby dowiedzieć się więcej: i interoperacyjność systemu od dostawcy.

Adnotacja nie zmienia podpisu typu, ale po jego ustawieniu instancja typu jest oznaczona jako stabilna, więc może się przemieszczać procesów dostawcy i systemu.

Adnotację można dołączyć tylko do deklaracji typu zdefiniowanego przez użytkownika, tak jak w tym przykładzie tutaj:

@VintfStability
interface IFoo {
    ....
}

@VintfStability
parcelable Data {
    ....
}

@VintfStability
enum Type {
    ....
}

Gdy typ jest oznaczony adnotacją VintfStability, każdy inny typ do określonego typu powinna być również opatrzona adnotacjami. W następujących np. Data i IBar powinny mieć adnotację VintfStability.

@VintfStability
interface IFoo {
    void doSomething(in IBar b); // references IBar
    void doAnother(in Data d); // references Data
}

@VintfStability // required
interface IBar {...}

@VintfStability // required
parcelable Data {...}

Dodatkowo pliki AIDL definiują typy z adnotacjami VintfStability można utworzyć tylko za pomocą typu modułu Soong aidl_interface z parametrem Właściwość stability została ustawiona na "vintf".

aidl_interface {
    name: "my_interface",
    srcs: [...],
    stability: "vintf",
}

Nieobsługiwane użycie aplikacji

Adnotacja UnsupportedAppUsage wskazuje, że z adnotacją typ AIDL to do interfejsu innego niż SDK, który był dostępny dla starszych aplikacji. Zobacz Ograniczenia dotyczące pakietów innych niż SDK .

Adnotacja UnsupportedAppUsage nie wpływa na działanie funkcji wygenerowany kod. Adnotacja dodaje tylko informację do wygenerowanej klasy Java za pomocą atrybutu Adnotacja w Javie o tej samej nazwie.

// in AIDL
@UnsupportedAppUsage
interface IFoo {...}

// in Java
@android.compat.annotation.UnsupportedAppUsage
public interface IFoo {...}

To ustawienie nie jest obsługiwane dla backendów innych niż Java.

Kopia zapasowa

Adnotacja Backing określa typ pamięci wyliczenia AIDL.

@Backing(type="int")
enum Color { RED, BLUE, }

W backendzie CPP generuje to klasę wyliczeniową C++ typu int32_t.

enum class Color : int32_t {
    RED = 0,
    BLUE = 1,
}

Jeśli adnotacja zostanie pominięta, przyjmuje się, że w polu type znajduje się wartość byte, która jest mapowana na int8_t dla backendu CPP.

Argument type można ustawić tylko na te typy całek:

  • byte (8-bitowy)
  • int (32-bitowy)
  • long (64-bitowy)

NdkOnlyStableParcelable,

NdkOnlyStableParcelable oznacza deklarację możliwości parlamentu (nie definicja) jako stabilną, tak aby można było się do niej odwoływać z innych stabilnych typów AIDL. Ten jest jak JavaOnlyStableParcelable, ale NdkOnlyStableParcelable oznacza deklarację 9K jako stabilną dla pakietu NDK z backendem zamiast Javy.

Aby użyć tej działki:

  • Musisz określić ndk_header.
  • Musisz mieć bibliotekę NDK określającą paczkę, a biblioteka a nie wszystkie w bibliotece. Na przykład w podstawowym systemie kompilacji cc_*, użyj static_libs lub shared_libs. Do aidl_interface dodaj biblioteki pod additional_shared_libraries w Android.bp.

JavaOnlyStableParcelable,

JavaOnlyStableParcelable oznacza deklarację możliwości parlamentu (nie definicja) jako stabilną, tak aby można było się do niej odwoływać z innych stabilnych typów AIDL.

Stabilna AIDL wymaga, aby wszystkie typy zdefiniowane przez użytkownika były stabilne. Dla: Parcelables, jest stabilny, więc jego pola muszą być wyraźnie opisane pliku źródłowego AIDL.

parcelable Data { // Data is a structured parcelable.
    int x;
    int y;
}

parcelable AnotherData { // AnotherData is also a structured parcelable
    Data d; // OK, because Data is a structured parcelable
}

Jeśli parcelable był nieuporządkowany (lub właśnie zadeklarowany), to nie można go wymienionych.

parcelable Data; // Data is NOT a structured parcelable

parcelable AnotherData {
    Data d; // Error
}

JavaOnlyStableParcelable pozwala zastąpić sprawdzanie, gdy pakiet są już bezpiecznie dostępne w pakiecie Android SDK.

@JavaOnlyStableParcelable
parcelable Data;

parcelable AnotherData {
    Data d; // OK
}

JavaDerive,

JavaDerive automatycznie generuje metody dla typów nieruchomości w Backend Javy.

@JavaDerive(equals = true, toString = true)
parcelable Data {
  int number;
  String str;
}

Adnotacja wymaga dodatkowych parametrów określających, co ma być co możesz wygenerować. Obsługiwane parametry:

  • Funkcja equals=true generuje metody equals i hashCode.
  • toString=true generuje metodę toString, która wyświetla nazwę typu i pól. Przykład: Data{number: 42, str: foo}

Ustawienie domyślne Java

JavaDefault, dodana w Androidzie 13, określa, czy generowana jest domyślna obsługa wersji implementacji (dla setDefaultImpl). Ta pomoc nie jest już domyślnie generowana, aby i oszczędzać miejsce.

Przekazywanie języka Java

JavaPassthrough umożliwia oznaczenie wygenerowanego interfejsu Java API za pomocą dowolnego Adnotacja w Javie.

Następujące adnotacje w AIDL

@JavaPassthrough(annotation="@android.annotation.Alice")
@JavaPassthrough(annotation="@com.android.Alice(arg=com.android.Alice.Value.A)")

stań się

@android.annotation.Alice
@com.android.Alice(arg=com.android.Alice.Value.A)

w wygenerowanym kodzie Java.

Wartość parametru annotation jest emitowana bezpośrednio. AIDL nie sprawdza wartości parametru. Jeśli są Błąd składni na poziomie Javy nie zostanie przechwycony przez kompilator AIDL, ale Kompilator Java.

Tę adnotację można dołączyć do dowolnej encji AIDL. Ta adnotacja nie jest obsługiwana dla backendów innych niż Java.

Stały rozmiar

FixedSize oznacza działkę strukturalną jako stały rozmiar. Po oznaczeniu parcelable, nie można dodawać do niego nowych pól. Wszystkie pola wartości Parcelable musi mieć też określone typy rozmiarów, w tym typy podstawowe, wyliczenia, tablice o stałym rozmiarze i inne elementy składowe oznaczone przy użyciu FixedSize.

Nie daje to żadnej gwarancji jakości działania i nie powinno korzysta się z komunikacji mieszanej.

Opis

Pole Descriptor wymuszone określa deskryptor interfejsu interfejsu.

package android.foo;

@Descriptor(value="android.bar.IWorld")
interface IHello {...}

Deskryptor tego interfejsu to android.bar.IWorld. Jeśli Brak adnotacji Descriptor. Deskryptor będzie android.foo.IHello

Przydaje się to do zmiany nazwy opublikowanego już interfejsu. Dbamy o środowisko deskryptor zmienionego interfejsu taki sam jak deskryptor interfejsu , zanim zmiana nazwy umożliwi komunikację pomiędzy tymi dwoma interfejsami.

@ukryj w komentarzach

Kompilator AIDL rozpoznaje tekst @hide w komentarzach i przekazuje go w Javie dla metalava do odbioru. Taki komentarz gwarantuje, że system kompilacji wie, że interfejsy API AIDL nie są interfejsami SDK.

@deprecated w komentarzach

Kompilator AIDL rozpoznaje w komentarzach tag @deprecated jako tag identyfikujący Encja AIDL, która nie powinna już być używana.

interface IFoo {
  /** @deprecated use bar() instead */
  void foo();
  void bar();
}

Każdy backend oznacza wycofane encje adnotacją specyficzną dla backendu lub dzięki czemu kod klienta będzie otrzymywać ostrzeżenie, jeśli będzie zawierać odniesienie do wycofanego podmiotów. Na przykład adnotacje @Deprecated i @deprecated są dołączone do kodu wygenerowanego w Javie.