AIDL unterstützt Anmerkungen, die dem AIDL-Compiler zusätzliche Informationen zum kommentierten Element geben, was sich auch auf den generierten Stub-Code auswirkt.
Die Syntax ähnelt der von Java:
@AnnotationName(argument1=value, argument2=value) AidlEntity
Dabei ist AnnotationName
der Name der Annotation und AidlEntity
eine AIDL-Entität wie interface Foo
, void method()
oder int arg
. Eine Anmerkung wird der nachfolgenden Einheit zugeordnet.
Für einige Anmerkungen können Argumente in den Klammern festgelegt werden, wie oben gezeigt. Bei Hinweisen ohne Argumente sind die Klammern nicht 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. Die Annotationen sind alle vordefiniert. Einige Anmerkungen wirken sich nur auf ein bestimmtes Backend aus und haben in anderen Backends keine Auswirkungen. Es gelten unterschiedliche Einschränkungen, wo sie angebracht werden dürfen.
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 |
nullable
nullable
deklariert, dass der Wert der annotierten Entität nicht angegeben werden darf.
Diese Annotation kann nur an Rückgabetypen von Methoden, Methodenparametern und Parcelable-Feldern 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;
}
Annotationen können nicht an einfache Typen angehängt werden. Das Folgende ist ein Fehler.
void method(in @nullable int a); // int is a primitive type
Diese Annotation hat keine Auswirkungen auf das Java-Backend. Das liegt daran, dass in Java alle nicht primitiven Typen als Referenz übergeben werden, was null
sein könnte.
Im CPP-Backend wird @nullable T
in Android 11 oder niedriger std::unique_ptr<T>
und in Android 12 oder höher std::optional<T>
zugeordnet.
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
std::optional<std::vector<std::optional<T>>>
zugeordnet (oder std::unique_ptr<std::vector<std::unique_ptr<T>>>
im Fall des CPP-Back-Ends für Android 11 oder niedriger).
Es gibt eine Ausnahme von dieser Zuordnung. Wenn T
IBinder
oder eine AIDL-Schnittstelle ist, ist @nullable
für alle Back-Ends außer Rust ein No-Op. Anders ausgedrückt: Sowohl @nullable IBinder
als auch IBinder
werden gleichermaßen android::sp<IBinder>
zugeordnet, was bereits nullable ist, da es sich um einen starken Pointer handelt (CPP-Lesevorgänge erzwingen weiterhin die Nullable-Eigenschaft, aber der Typ ist weiterhin android::sp<IBinder>
). In Rust sind diese Typen nur nullable
, wenn sie mit @nullable
annotiert sind. Sie werden Option<T>
zugeordnet, wenn sie mit Anmerkungen versehen sind.
Ab Android 13 kann @nullable(heap=true)
für parcelable-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 wird, wird es in den CPP-/NDK-Back-Ends einer heap-zugeordneten Referenz std::unique_ptr<T>
zugeordnet. @nullable(heap=true)
ist im Java-Backend ein No-Op.
utf8InCpp
utf8InCpp
deklariert, dass ein String
im UTF8-Format für das CPP-Backend dargestellt wird. Wie der Name schon sagt, ist die Annotation für andere Backends ein No-Op.
Insbesondere ist String
im Java-Backend immer UTF16 und im NDK-Backend UTF8.
Diese Annotation kann überall angehängt werden, wo der Typ String
verwendet werden kann, einschließlich Rückgabewerten, Parametern, Konstantendeklarationen und Parcelable-Feldern.
Im CPP-Backend wird @utf8InCpp String
in AIDL std::string
zugeordnet, während String
ohne die Annotation android::String16
zugeordnet wird, wobei UTF16 verwendet wird.
Das Vorhandensein der Annotation utf8InCpp
ändert nichts daran, wie Strings über das Netzwerk übertragen werden. Strings werden immer als UTF16 über das Netzwerk ü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
gekennzeichnet wurde.
VintfStability
VintfStability
deklariert, dass ein benutzerdefinierter Typ (Schnittstelle, Parcelable und Enum) in allen System- und Anbieterdomains verwendet werden kann. Weitere Informationen zur Interoperabilität zwischen System und Anbieter finden Sie unter AIDL für HALs.
Die Annotation ändert die Signatur des Typs nicht. Wenn sie jedoch festgelegt ist, wird die Instanz des Typs als stabil markiert, sodass sie zwischen den Anbieter- und Systemprozessen übertragen werden kann.
Die Anmerkung 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 ist, sollte jeder andere Typ, auf den im Typ verwiesen wird, ebenfalls so 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, in denen mit VintfStability
annotierte Typen definiert werden, nur mit dem Soong-Modultyp aidl_interface
erstellt werden, wobei das Attribut stability
auf "vintf"
festgelegt ist.
aidl_interface {
name: "my_interface",
srcs: [...],
stability: &
quot;vintf",
}
UnsupportedAppUsage
Die Annotation UnsupportedAppUsage
gibt an, dass der annotierte AIDL-Typ Teil der Nicht-SDK-Schnittstelle ist, die für Legacy-Apps zugänglich war.
Weitere Informationen zu den verborgenen APIs finden Sie unter Einschränkungen für Nicht-SDK-Schnittstellen.
Die Annotation UnsupportedAppUsage
hat keine Auswirkungen auf das Verhalten des generierten Codes. Die Annotation annotiert nur die generierte Java-Klasse mit der gleichnamigen Java-Annotation.
// in AIDL
@UnsupportedAppUsage
interface IFoo {...}
// in Java
@android.compat.annotation.UnsupportedAppUsage
public interface IFoo {...}
Für Back-Ends, die nicht auf Java basieren, hat diese Methode keine Auswirkungen.
Rücken
Mit der Annotation Backing
wird der Speichertyp eines AIDL-Enum-Typs angegeben.
@Backing(type="int")
enum Color { RED
, BLUE, }
Im CPP-Backend wird dadurch eine C++-Enum-Klasse vom Typ int32_t
ausgegeben.
enum class Color : int32_t {
RED = 0,
BLUE = 1,
}
Wird die Annotation weggelassen, wird davon ausgegangen, dass type
gleich byte
ist, was für das CPP-Backend int8_t
entspricht.
Das Argument type
kann nur auf die folgenden integralen Typen festgelegt werden:
byte
(8 Bit breit)int
(32 Bit breit)long
(64 Bit breit)
NdkOnlyStableParcelable
NdkOnlyStableParcelable
kennzeichnet eine Parcelable-Deklaration (nicht Definition) als stabil, sodass sie von anderen stabilen AIDL-Typen referenziert werden kann. Dies entspricht JavaOnlyStableParcelable
, aber NdkOnlyStableParcelable
kennzeichnet eine Parcelable-Deklaration als stabil für das NDK-Backend anstelle von Java.
So verwenden Sie dieses Parcelable:
- Sie müssen
ndk_header
angeben. - Sie benötigen eine NDK-Bibliothek, in der das Parcelable angegeben ist. Die Bibliothek muss in die Bibliothek kompiliert werden. Verwenden Sie beispielsweise im Core-Build-System für ein
cc_*
-Modulstatic_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 sie von anderen stabilen AIDL-Typen referenziert werden kann.
Für stabiles AIDL müssen alle benutzerdefinierten Typen stabil sein. Damit Parcelables stabil sind, müssen ihre 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 Parcelable unstrukturiert (oder nur 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 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 Parcelable-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
, mit der der Name des Typs und der Felder ausgegeben wird. Beispiel:Data{number: 42, str: foo}
JavaDefault
JavaDefault
, die in Android 13 hinzugefügt wurde, steuert, ob die Versionsverwaltung der Standardimplementierung 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.Al
ice.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 ausgegeben. Der AIDL-Compiler berücksichtigt den Wert des Parameters nicht. Syntaxfehler auf Java-Ebene werden nicht vom AIDL-Compiler, sondern vom Java-Compiler erkannt.
Diese Annotation kann an jede AIDL-Entität angehängt werden. Diese Annotation hat keine Auswirkungen auf Backends, die nicht auf Java basieren.
RustDerive
RustDerive
implementiert automatisch Traits für generierte Rust-Typen.
Für die Anmerkung sind zusätzliche Parameter erforderlich, um zu steuern, was generiert werden soll. Folgende Parameter werden unterstützt:
Copy=true
Clone=true
Ord=true
PartialOrd=true
Eq=true
PartialEq=true
Hash=true
Erläuterungen zu diesen Traits finden Sie unter https://doc.rust-lang.org.
FixedSize
FixedSize
markiert ein strukturiertes Parcelable als feste Größe. Sobald das Parcelable markiert ist, dürfen keine neuen Felder mehr hinzugefügt werden. Alle Felder des Parcelable-Objekts müssen auch Typen mit fester Größe sein, einschließlich primitiver Typen, Enums, Arrays mit fester Größe und anderer Parcelable-Objekte, die mit FixedSize
gekennzeichnet sind.
Es gibt keine Garantie für unterschiedliche Bitbreiten und es sollte nicht für die Kommunikation mit gemischten Bitbreiten verwendet werden.
Beschreibung
Descriptor
gibt den Schnittstellendescriptor einer Schnittstelle explizit an.
package android.foo;
@Descriptor(value="android.bar.IWorld")
interface IHe
llo {...}
Der Deskriptor dieser Schnittstelle ist android.bar.IWorld
. Wenn die Anmerkung Descriptor
fehlt, lautet der Deskriptor android.foo.IHello
.
Das ist nützlich, um eine bereits veröffentlichte Schnittstelle umzubenennen. Wenn Sie den Deskriptor der umbenannten Schnittstelle mit dem Deskriptor der Schnittstelle vor der Umbenennung identisch machen, 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 Metalava es erfassen kann. Dieser Kommentar sorgt dafür, dass das Android-Build-System weiß, dass AIDL-APIs keine SDK-APIs sind.
@deprecated in Kommentaren
Der AIDL-Compiler erkennt @deprecated
in Kommentaren als Tag, um eine AIDL-Entität zu identifizieren, die nicht mehr verwendet werden sollte.
interface IFoo {
/** @deprecated use bar() instead */
void foo();
void bar();
}
Jedes Backend kennzeichnet eingestellte Entitäten mit einer backend-spezifischen Annotation oder einem Attribut, sodass der Clientcode gewarnt wird, wenn er auf die eingestellten Entitäten verweist. Die Annotation @Deprecated
und das Tag @deprecated
werden beispielsweise an den generierten Java-Code angehängt.