AIDL unterstützt Annotationen, die dem AIDL-Compiler zusätzliche Informationen über das annotierte 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 Annotation und AidlEntity
eine AIDL-Entität wie interface Foo
, void method()
oder int arg
. Eine Anmerkung wird an die darauffolgende Entität angehängt.
Bei einigen Anmerkungen können Argumente in Klammern gesetzt werden, wie oben gezeigt. Anmerkungen, die kein Argument enthalten, benötigen keine Klammer. Beispiel:
@AnnotationName AidlEntity
Diese Annotationen sind nicht mit den Java-Annotationen identisch, sehen aber sehr ähnlich aus. 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. Sie haben unterschiedliche Einschränkungen, an die sie angehängt werden können.
Hier ist die Liste der vordefinierten AIDL-Annotationen:
Anmerkungen | In 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 |
Nullwerte zulässig
nullable
gibt an, dass der Wert der annotierten Entität nicht angegeben werden darf.
Diese Annotation kann nur an Methodenrückgabetypen, Methodenparameter und geparste 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;
}
An primitive Typen können keine Anmerkungen angehängt werden. Folgendes ist ein Fehler.
void method(in @nullable int a); // int is a primitive type
Diese Annotation ist für das Java-Back-End managementfrei. Das liegt daran, dass in Java alle nicht primitiven Typen durch einen Verweis übergeben werden, der null
sein kann.
Im CPP-Back-End wird @nullable T
unter Android 11 oder niedriger std::unique_ptr<T>
und in Android 12 oder höher std::optional<T>
zugeordnet.
Im NDK-Back-End wird @nullable T
immer std::optional<T>
zugeordnet.
Bei einem listenähnlichen Typ L
wie T[]
oder List<T>
wird @nullable L
std::optional<std::vector<std::optional<T>>>
(oder std::unique_ptr<std::vector<std::unique_ptr<T>>>
im Fall des CPP-Back-Ends für Android 11 oder niedriger) zugeordnet.
Für diese Zuordnung gibt es eine Ausnahme. Wenn T
IBinder
oder eine AIDL-Schnittstelle ist, ist @nullable
kein Vorgang. Mit anderen Worten, sowohl @nullable IBinder
als auch IBinder
sind gleichermaßen android::sp<IBinder>
zugeordnet, was bereits Null-Zulässigkeit ist, da es ein starker Zeiger ist (CPP-Lesevorgänge erzwingen weiterhin Null-Zulässigkeit, aber der Typ ist weiterhin android::sp<IBinder>
).
Ab Android 13 kann @nullable(heap=true)
für Pakete verwendet werden, um rekursive Typen zu modellieren. @nullable(heap=true)
kann nicht mit Methodenparametern oder Rückgabetypen verwendet werden. Wenn das Feld damit annotiert wird, wird es einem Heap-zugewiesenen Verweis std::unique_ptr<T>
in den CPP-/NDK-Back-Ends zugeordnet. @nullable(heap=true)
ist im Java-Back-End managementfrei.
utf8InCpp
utf8InCpp
deklariert, dass ein String
für das CPP-Back-End im UTF8-Format dargestellt wird. Wie der Name schon sagt, ist die Annotation eine Nulloperation für andere Back-Ends.
Insbesondere ist String
im Java-Back-End immer UTF16 und im NDK-Back-End UTF8.
Diese Annotation kann überall dort angehängt werden, wo der Typ String
verwendet werden kann, einschließlich Rückgabewerten, Parametern, konstanten Deklarationen und Paketfeldern.
Für das CPP-Back-End wird @utf8InCpp String
in AIDL std::string
zugeordnet, während String
ohne Annotation android::String16
zugeordnet wird, wenn UTF16 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 UTF16 über das Kabel übertragen. Ein mit utf8InCpp
annotierter String wird vor der Übertragung in UTF16 konvertiert. Wenn ein String empfangen wird, wird er von UTF16 in UTF8 konvertiert, wenn er als utf8InCpp
annotiert war.
vintfStabilität
VintfStability
deklariert, dass ein benutzerdefinierter Typ (Schnittstelle, Paket und Enum) in allen System- und Anbieterdomains verwendet werden kann. Weitere Informationen zur Interoperabilität zwischen Systemanbietern 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 {
....
}
Wird ein Typ mit VintfStability
annotiert, 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
annotiert werden.
@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",
}
Nicht unterstützte App-Nutzung
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 bei Nicht-SDK-Schnittstellen.
Die Annotation UnsupportedAppUsage
hat keinen Einfluss auf das Verhalten des generierten Codes. Die Annotation annotiert nur die generierte Java-Klasse mit der Java-Annotation desselben Namens.
// in AIDL
@UnsupportedAppUsage
interface IFoo {...}
// in Java
@android.compat.annotation.UnsupportedAppUsage
public interface IFoo {...}
Dies ist ein No-Op für Nicht-Java-Back-Ends.
Rückenlehnen
Die Annotation Backing
gibt den Speichertyp eines AIDL-Enum-Typs an.
@Backing(type="int")
enum Color { RED, BLUE, }
Im CPP-Back-End gibt dies eine C++-Enum-Klasse vom Typ int32_t
aus.
enum class Color : int32_t {
RED = 0,
BLUE = 1,
}
Wenn die Annotation weggelassen wird, wird davon ausgegangen, dass type
byte
ist, was int8_t
für das CPP-Back-End zugeordnet ist.
Das Argument type
kann nur auf die folgenden ganzzahligen Typen festgelegt werden:
byte
(8-Bit-Breite)int
(32-Bit-Breite)long
(64-Bit-Breite)
NdkOnlyStableParcelable
NdkOnlyStableParcelable
kennzeichnet eine Paketdeklaration (keine Definition) als stabil, damit von anderen stabilen AIDL-Typen darauf verwiesen werden kann. Dies entspricht JavaOnlyStableParcelable
, allerdings markiert NdkOnlyStableParcelable
eine Parzellendeklaration als stabil für das NDK-Back-End und nicht für Java.
So verwenden Sie dieses Paket:
- Sie müssen
ndk_header
angeben. - Sie benötigen eine NDK-Bibliothek, die das Parcelable angibt, und die Bibliothek muss in die Bibliothek kompiliert werden. Verwenden Sie beispielsweise im zentralen 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 Paketdeklaration (keine Definition) als stabil, damit von anderen stabilen AIDL-Typen darauf verwiesen werden kann.
Für den stabilen AIDL müssen alle benutzerdefinierten Typen stabil sein. Für die Stabilität von Paketen müssen die Felder explizit in der AIDL-Quelldatei 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 Paket unstrukturiert (oder gerade deklariert) war, kann nicht darauf verwiesen 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 Paket, auf das Sie verweisen, bereits als Teil des Android SDK sicher verfügbar ist.
@JavaOnlyStableParcelable
parcelable Data;
parcelable AnotherData {
Data d; // OK
}
JavaDerive
JavaDerive
generiert automatisch Methoden für Pakettypen im Java-Back-End.
@JavaDerive(equals = true, toString = true)
parcelable Data {
int number;
String str;
}
Die Annotation erfordert zusätzliche Parameter, 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}
JavaStandard
JavaDefault
, das in Android 13 hinzugefügt wurde, steuert, ob die Unterstützung für die standardmäßige Implementierungsversionsverwaltung (für setDefaultImpl
) generiert wird. 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 Annotationen 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 ein.
Der Wert des Parameters annotation
wird direkt ausgegeben. Der AIDL-Compiler berücksichtigt den Wert des Parameters nicht. Ein Syntaxfehler auf Java-Ebene wird nicht vom AIDL-Compiler, sondern vom Java-Compiler abgefangen.
Diese Annotation kann an jede AIDL-Entität angehängt werden. Diese Annotation ist bei Nicht-Java-Back-Ends ein Leerbefehl.
Feste Größe
FixedSize
kennzeichnet ein strukturiertes Flurstück als feste Größe. Nach dem Markieren können dem Paket keine neuen Felder mehr hinzugefügt werden. Alle Felder des Pakets müssen auch 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 zwangsweise den Schnittstellendeskriptor einer Schnittstelle an.
package android.foo;
@Descriptor(value="android.bar.IWorld")
interface IHello {...}
Der Deskriptor dieser Schnittstelle ist android.bar.IWorld
. Wenn die Annotation Descriptor
fehlt, lautet der Deskriptor android.foo.IHello
.
Dies ist hilfreich, wenn Sie eine bereits veröffentlichte Schnittstelle umbenennen möchten. Wenn Sie vor der Umbenennung den Deskriptor der umbenannten Schnittstelle mit dem Deskriptor der Schnittstelle identisch machen, können die beiden Schnittstellen miteinander kommunizieren.
In Kommentaren @ausblenden
Der AIDL-Compiler erkennt @hide
in Kommentaren und übergibt ihn an die Java-Ausgabe, damit Metalava verarbeitet werden kann. Dieser Kommentar sorgt dafür, dass das Android-Build-System erkennt, dass AIDL APIs keine SDK APIs sind.
@eingestellt in Kommentaren
Der AIDL-Compiler erkennt @deprecated
in Kommentaren als Tag zum Identifizieren einer AIDL-Entität, die nicht mehr verwendet werden sollte.
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.