AIDL unterstützt Anmerkungen, die dem AIDL-Compiler zusätzliche Informationen zum annotierten Element liefern. Dies wirkt sich auch auf den generierten Stub-Code aus.
Die Syntax ähnelt der von Java:
@AnnotationName(argument1=value, argument2=value) AidlEntity
Hier ist AnnotationName
der Name der Anmerkung und AidlEntity
ist eine AIDL-Entität wie interface Foo
, void method()
oder int arg
. Eine Anmerkung wird an die darauffolgende Entität angehängt.
Einige Anmerkungen können Argumente in den Klammern haben, wie oben gezeigt. Bei Anmerkungen ohne Argument sind keine Klammern erforderlich. Beispiel:
@AnnotationName AidlEntity
Diese Anmerkungen sind nicht mit den Java-Anmerkungen identisch, obwohl sie sehr ähnlich aussehen. Nutzer können keine benutzerdefinierten AIDL-Annotationen definieren. Alle Annotationen sind vordefiniert. Einige Annotationen wirken sich nur auf ein bestimmtes Back-End aus und sind in anderen Back-Ends nicht funktionsfähig. Für sie gelten unterschiedliche Einschränkungen, wo sie angebracht werden können.
Hier ist eine Liste der vordefinierten AIDL-Anmerkungen:
Anmerkungen | In der Android-Version hinzugefügt |
---|---|
nullable |
7 |
utf8InCpp |
7 |
VintfStability |
11 |
UnsupportedAppUsage |
10 |
Hide |
11 |
Backing |
11 |
NdkOnlyStableParcelable |
14 |
JavaOnlyStableParcelable |
11 |
JavaDerive |
12 |
JavaPassthrough |
12 |
FixedSize |
12 |
Descriptor |
12 |
nullable
nullable
gibt an, dass der Wert der annotierten Entität möglicherweise nicht angegeben wird.
Diese Anmerkung kann nur an Methodenrückgabetypen, Methodenparameter und parzellierbare Felder angehängt werden.
interface IFoo {
// method return types
@nullable Data method();
// method parameters
void method2(in @nullable Data d);
}
parcelable Data {
// parcelable fields
@nullable Data d;
}
Anmerkungen können nicht an primitive Typen angehängt werden. Folgendes ist ein Fehler.
void method(in @nullable int a); // int is a primitive type
Diese Anmerkung hat für das Java-Backend keine Auswirkungen. Das liegt daran, dass in Java alle nicht primitiven Typen per Verweis übergeben werden, was null
sein könnte.
Im CPP-Backend wird @nullable T
unter Android 11 oder niedriger mit std::unique_ptr<T>
und unter Android 12 oder höher mit std::optional<T>
abgeglichen.
Im NDK-Backend wird @nullable T
immer std::optional<T>
zugeordnet.
Im Rust-Back-End wird @nullable T
immer Option<T>
zugeordnet.
Bei einem listenähnlichen Typ L
wie T[]
oder List<T>
wird @nullable L
auf std::optional<std::vector<std::optional<T>>>
(oder std::unique_ptr<std::vector<std::unique_ptr<T>>>
im Fall des CPP-Backends für Android 11 oder niedriger) abgebildet.
Für diese Zuordnung gibt es eine Ausnahme. Wenn T
IBinder
oder eine AIDL-Schnittstelle ist, ist @nullable
für alle Back-Ends außer Rust eine Null-Operation. Mit anderen Worten: Sowohl @nullable IBinder
als auch IBinder
werden gleichermaßen auf android::sp<IBinder>
abgebildet, das bereits nullable ist, da es sich um einen starken Pointer handelt. Bei C++-Lesevorgängen wird weiterhin die Nullable-Eigenschaft erzwungen, der Typ ist jedoch weiterhin android::sp<IBinder>
. In Rust sind diese Typen nur dann nullable
, wenn sie mit @nullable
annotiert sind. Sie werden Option<T>
zugeordnet, wenn sie kommentiert sind.
Ab Android 13 kann @nullable(heap=true)
für parzellierbare Felder verwendet werden, um rekursive Typen zu modellieren. @nullable(heap=true)
kann nicht mit Methodenparametern oder Rückgabetypen verwendet werden. Wenn das Feld damit annotiert ist, wird es in den CPP/NDK-Backends einer heap-allozierten Referenz std::unique_ptr<T>
zugeordnet. @nullable(heap=true)
ist im Java-Backend eine Null-Operation.
utf8InCpp
utf8InCpp
gibt an, dass ein String
im UTF-8-Format für das CPP-Backend dargestellt wird. Wie der Name schon sagt, hat die Anmerkung für andere Back-Ends keine Auswirkungen.
Im Java-Backend ist String
immer UTF-16 und im NDK-Backend UTF-8.
Diese Anmerkung kann überall angebracht werden, wo der Typ String
verwendet werden kann, einschließlich Rückgabewerten, Parametern, Konstantendeklarationen und Parcelable-Feldern.
Für das CPP-Backend wird @utf8InCpp String
in AIDL std::string
zugeordnet, während String
ohne Anmerkung android::String16
zugeordnet wird, wenn UTF-16 verwendet wird.
Das Vorhandensein der Annotation utf8InCpp
hat keinen Einfluss auf die Art und Weise, wie Strings über das Kabel übertragen werden. Strings werden immer als UTF-16 übertragen. Ein mit utf8InCpp
annotierter String wird vor der Übertragung in UTF-16 konvertiert. Wenn ein String empfangen wird, wird er von UTF-16 in UTF-8 konvertiert, wenn er als utf8InCpp
gekennzeichnet wurde.
vintfStabilität
VintfStability
deklariert, dass ein benutzerdefinierter Typ (interface, parcelable und enum) system- und anbieterübergreifend verwendet werden kann. Weitere Informationen zur Interoperabilität zwischen System und Anbieter finden Sie unter AIDL für HALs.
Durch die Annotation wird die Signatur des Typs nicht geändert. Wenn sie jedoch festgelegt wird, wird die Instanz des Typs als stabil markiert, damit sie zwischen den Anbieter- und Systemprozessen übertragen werden kann.
Die Annotation kann nur an benutzerdefinierte Typdeklarationen angehängt werden, wie hier gezeigt:
@VintfStability
interface IFoo {
....
}
@VintfStability
parcelable Data {
....
}
@VintfStability
enum Type {
....
}
Wenn ein Typ mit VintfStability
annotiert wird, sollten alle anderen Typen, auf die im Typ verwiesen wird, ebenfalls entsprechend annotiert werden. Im folgenden Beispiel sollten sowohl Data
als auch IBar
mit VintfStability
gekennzeichnet sein.
@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 {...}
Außerdem können die AIDL-Dateien, die mit VintfStability
annotierte Typen definieren, nur mit dem Soong-Modultyp aidl_interface
erstellt werden, wobei das Attribut stability
auf "vintf"
gesetzt ist.
aidl_interface {
name: "my_interface",
srcs: [...],
stability: "vintf",
}
UnsupportedAppUsage
Die Annotation UnsupportedAppUsage
zeigt an, dass der annotierte AIDL-Typ Teil der Nicht-SDK-Schnittstelle ist, auf die Legacy-Anwendungen Zugriff haben.
Weitere Informationen zu den ausgeblendeten APIs finden Sie unter Einschränkungen für Nicht-SDK-Schnittstellen.
Die Annotation UnsupportedAppUsage
hat keinen Einfluss auf das Verhalten des generierten Codes. Die Annotation fügt nur der generierten Java-Klasse die Java-Annotation mit demselben Namen hinzu.
// in AIDL
@UnsupportedAppUsage
interface IFoo {...}
// in Java
@android.compat.annotation.UnsupportedAppUsage
public interface IFoo {...}
Für andere Back-Ends ist dies nicht erforderlich.
Unterlage
Die Anmerkung Backing
gibt den Speichertyp eines AIDL-Enumtyps an.
@Backing(type="int")
enum Color { RED, BLUE, }
Im CPP-Backend wird dadurch eine C++-Enum-Klasse vom Typ int32_t
generiert.
enum class Color : int32_t {
RED = 0,
BLUE = 1,
}
Wird die Anmerkung weggelassen, wird für type
byte
angenommen, was für das CPP-Backend zu int8_t
führt.
Das Argument type
kann nur auf die folgenden Ganzzahltypen festgelegt werden:
byte
(8 Bit breit)int
(32 Bit breit)long
(64-Bit-Breite)
NdkOnlyStableParcelable
NdkOnlyStableParcelable
kennzeichnet eine Paketdeklaration (keine Definition) als stabil, damit von anderen stabilen AIDL-Typen darauf verwiesen werden kann. Das ist ähnlich wie JavaOnlyStableParcelable
, aber NdkOnlyStableParcelable
kennzeichnet eine Parcelable-Deklaration als stabil für das NDK-Backend anstelle von Java.
So verwenden Sie diese Parcelable:
- Sie müssen
ndk_header
angeben. - Sie benötigen eine NDK-Bibliothek, in der das Parcelable angegeben ist, und die Bibliothek muss in die Bibliothek kompiliert werden. Verwenden Sie beispielsweise im Kern-Build-System eines
cc_*
-Modulsstatic_libs
odershared_libs
. Fügen Sie füraidl_interface
die Bibliothek unteradditional_shared_libraries
inAndroid.bp
hinzu.
JavaOnlyStableParcelable
JavaOnlyStableParcelable
kennzeichnet eine Parcelable-Deklaration (nicht Definition) als stabil, sodass darauf von anderen stabilen AIDL-Typen verwiesen werden kann.
Für stabile AIDL-Dateien müssen alle benutzerdefinierten Typen stabil sein. Damit Parcelable-Objekte stabil sind, müssen ihre Felder in der AIDL-Quelldatei explizit beschrieben werden.
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
}
Wenn das Parcelable unstrukturiert (oder nur deklariert) war, kann es nicht referenziert werden.
parcelable Data; // Data is NOT a structured parcelable
parcelable AnotherData {
Data d; // Error
}
Mit JavaOnlyStableParcelable
können Sie die Prüfung überschreiben, wenn das Parcelable, auf das Sie verweisen, bereits sicher als Teil des Android SDK verfügbar ist.
@JavaOnlyStableParcelable
parcelable Data;
parcelable AnotherData {
Data d; // OK
}
JavaDerive
JavaDerive
generiert automatisch Methoden für paketbare Typen im Java-Backend.
@JavaDerive(equals = true, toString = true)
parcelable Data {
int number;
String str;
}
Für die Anmerkung sind zusätzliche Parameter erforderlich, um zu steuern, was generiert werden soll. Folgende Parameter werden unterstützt:
equals=true
generiert die Methodenequals
undhashCode
.toString=true
generiert die MethodetoString
, die den Namen des Typs und der Felder ausgibt. Beispiel:Data{number: 42, str: foo}
JavaDefault
JavaDefault
, in Android 13 hinzugefügt, steuert, ob die Standardimplementierung für die Versionsverwaltung generiert wird (für setDefaultImpl
). Diese Unterstützung wird nicht mehr standardmäßig generiert, um Speicherplatz zu sparen.
JavaPassthrough
Mit JavaPassthrough
kann die generierte Java API mit einer beliebigen Java-Annotation annotiert werden.
Die folgenden Anmerkungen in AIDL
@JavaPassthrough(annotation="@android.annotation.Alice")
@JavaPassthrough(annotation="@com.android.Alice(arg=com.android.Alice.Value.A)")
werden
@android.annotation.Alice
@com.android.Alice(arg=com.android.Alice.Value.A)
im generierten Java-Code.
Der Wert des Parameters annotation
wird direkt gesendet. Der AIDL-Compiler prüft den Wert des Parameters nicht. Ein Syntaxfehler auf Java-Ebene wird nicht vom AIDL-Compiler, sondern vom Java-Compiler abgefangen.
Diese Anmerkung kann an jede AIDL-Entität angehängt werden. Diese Anmerkung hat für Nicht-Java-Backends keine Auswirkungen.
FixedSize
FixedSize
kennzeichnet ein strukturiertes Parcelable als feste Größe. Danach können dem Parcelable keine neuen Felder hinzugefügt werden. Alle Felder des Pakets müssen ebenfalls Typen mit fester Größe haben, einschließlich primitiver Typen, Enums, Arrays mit fester Größe und anderer Parzellen, die mit FixedSize
gekennzeichnet sind.
Dies bietet keine Garantie für verschiedene Bits und sollte nicht für eine Kommunikation mit gemischter Bitqualität verwendet werden.
Beschreibung
Descriptor
gibt den Interface-Descriptor einer Schnittstelle erzwungen an.
package android.foo;
@Descriptor(value="android.bar.IWorld")
interface IHello {...}
Der Descriptor dieser Schnittstelle ist android.bar.IWorld
. Wenn die Anmerkung Descriptor
fehlt, lautet der Deskriptor android.foo.IHello
.
Dies ist hilfreich, wenn Sie eine bereits veröffentlichte Schnittstelle umbenennen möchten. Wenn der Deskriptor der umbenannten Schnittstelle mit dem Deskriptor der Schnittstelle vor der Umbenennung übereinstimmt, können die beiden Schnittstellen miteinander kommunizieren.
@hide in comments
Der AIDL-Compiler erkennt @hide
in Kommentaren und gibt es an die Java-Ausgabe weiter, damit es von Metalava übernommen werden kann. Dieser Kommentar sorgt dafür, dass das Android-Build-System weiß, dass AIDL-APIs keine SDK-APIs sind.
@deprecated in comments
Der AIDL-Compiler erkennt @deprecated
in Kommentaren als Tag, um eine AIDL-Entität zu identifizieren, die nicht mehr verwendet werden soll.
interface IFoo {
/** @deprecated use bar() instead */
void foo();
void bar();
}
Jedes Back-End markiert verworfene Entitäten mit einer Back-End-spezifischen Anmerkung oder einem Back-End-Attribut, sodass der Clientcode gewarnt wird, wenn er auf die verworfenen Entitäten verweist. Beispielsweise werden die Annotation @Deprecated
und das Tag @deprecated
an den von Java generierten Code angehängt.