AIDL unterstützt Annotationen, die dem AIDL-Compiler zusätzliche Informationen über das annotierte Element geben, was sich auch auf den generierten Stub-Code auswirkt.
Die Syntax ähnelt der von Java:
@AnnotationName(argument1=value, argument2=value) AidlEntity
Hier ist AnnotationName
der Name der Annotation und AidlEntity
ist eine AIDL-Entität wie interface Foo
, void method()
oder int arg
. Eine Anmerkung wird an die nachfolgende Entität angehängt.
Bei einigen Anmerkungen können Argumente in Klammern gesetzt werden, wie oben gezeigt. Anmerkungen ohne Argument benötigen keine Klammer. Zum Beispiel:
@AnnotationName AidlEntity
Diese Anmerkungen sind nicht mit den Java-Anmerkungen identisch, obwohl sie sehr ähnlich aussehen. Benutzer können keine benutzerdefinierten AIDL-Anmerkungen definieren; Die Anmerkungen sind alle vordefiniert. Einige Anmerkungen wirken sich nur auf ein bestimmtes Backend aus und sind in anderen Backends no-op. Sie haben unterschiedliche Beschränkungen, an denen sie angebracht werden können.
Unten ist die Liste der vordefinierten AIDL-Anmerkungen:
Anmerkungen | In der Android-Version hinzugefügt |
---|---|
nullable | 7 |
utf8InCpp | 7 |
VintfStability | 11 |
UnsupportedAppUsage | 10 |
Hide | 11 |
Backing | 11 |
JavaOnlyStableParcelable | 11 |
JavaDerive | 12 |
JavaPassthrough | 12 |
FixedSize | 12 |
Descriptor | 12 |
nullable
nullable
deklariert, dass der Wert der annotierten Entität nicht bereitgestellt werden darf.
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 ist für das Java-Back-End no-op. Dies liegt daran, dass in Java alle nicht primitiven Typen als Referenz übergeben werden, die null
sein könnte.
Im CPP-Back-End wird @nullable T
std::unique_ptr<T>
in Android 11 oder niedriger und std::optional<T>
in Android 12 oder höher zugeordnet.
Im NDK-Backend wird @nullable T
immer std::optional<T>
zugeordnet.
Für einen 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 Falle des CPP-Backends für Android 11 oder niedriger).
Es gibt eine Ausnahme von dieser Zuordnung. Wenn T
IBinder
oder eine AIDL-Schnittstelle ist, ist @nullable
no-op. Mit anderen Worten, sowohl @nullable IBinder
als IBinder
werden gleichermaßen auf android::sp<IBinder>
, was bereits nullable ist, weil es ein starker Zeiger ist (CPP-Lesevorgänge erzwingen immer noch die Nullfähigkeit, aber der Typ ist immer noch android::sp<IBinder>
).
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 es damit annotiert wird, wird das Feld in den CPP/NDK-Backends einer Heap-zugewiesenen Referenz std::unique_ptr<T>
zugeordnet. @nullable(heap=true)
ist im Java-Backend 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 ein No-Op für andere Backends. Insbesondere ist String
im Java-Backend immer UTF16 und im NDK-Backend UTF8.
Diese Anmerkung kann überall dort angehängt werden, wo der String
-Typ verwendet werden kann, einschließlich Rückgabewerten, Parametern, Konstantendeklarationen und parzellierbaren Feldern.
Für das CPP-Backend wird @utf8InCpp String
in AIDL std::string
zugeordnet, während String
ohne die Anmerkung android::String16
wird, wo UTF16 verwendet wird.
Beachten Sie, dass das Vorhandensein der Annotation utf8InCpp
die Art und Weise, wie Zeichenfolgen über das Kabel übertragen werden, nicht ändert. Strings werden immer als UTF16 über die Leitung ü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
kommentiert wurde.
VintfStabilität
VintfStability
deklariert, dass ein benutzerdefinierter Typ (Schnittstelle, Paketierbar und Enum) über die System- und Anbieterdomänen hinweg verwendet werden kann. Weitere Informationen zur Interoperabilität zwischen Systemanbietern finden Sie unter AIDL für HALs .
Die Anmerkung ändert die Signatur des Typs nicht, aber wenn sie gesetzt ist, wird die Instanz des Typs als stabil markiert, damit sie die Anbieter- und Systemprozesse durchlaufen kann.
Die Annotation kann nur wie unten gezeigt an benutzerdefinierte Typdeklarationen angehängt werden:
@VintfStability
interface IFoo {
....
}
@VintfStability
parcelable Data {
....
}
@VintfStability
enum Type {
....
}
Wenn ein Typ mit VintfStability
kommentiert wird, sollte jeder andere Typ, auf den im Typ verwiesen wird, auch als solcher kommentiert werden. Im folgenden Beispiel sollten Data
und IBar
beide mit VintfStability
kommentiert 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 {...}
Darüber hinaus können die AIDL-Dateien, die mit VintfStability
kommentierte Typen definieren, nur mit dem aidl_interface
Soong erstellt werden, wobei die Eigenschaft " stability
" auf "vintf"
.
aidl_interface {
name: "my_interface",
srcs: [...],
stability: "vintf",
}
Nicht unterstützte App-Nutzung
Die Annotation UnsupportedAppUsage
gibt an, dass der kommentierte AIDL-Typ Teil der Nicht-SDK-Schnittstelle ist, auf die ältere Apps zugreifen können. Weitere Informationen zu den versteckten APIs finden Sie unter Einschränkungen für Nicht-SDK-Schnittstellen .
Die UnsupportedAppUsage
-Annotation wirkt sich nicht auf das Verhalten des generierten Codes aus. Die Annotation annotiert lediglich die generierte Java-Klasse mit der gleichnamigen Java-Annotation.
// in AIDL
@UnsupportedAppUsage
interface IFoo {...}
// in Java
@android.compat.annotation.UnsupportedAppUsage
public interface IFoo {...}
Dies ist ein No-Op für Nicht-Java-Backends.
Unterstützung
Die Backing
-Anmerkung gibt den Speichertyp eines AIDL-Aufzählungstyps an.
@Backing(type="int")
enum Color { RED, BLUE, }
Im CPP-Backend gibt das Obige eine C++-Enumerationsklasse vom Typ int32_t
aus.
enum class Color : int32_t {
RED = 0,
BLUE = 1,
}
Wenn die Anmerkung weggelassen wird, wird angenommen, dass der type
byte
ist, was für das CPP-Backend auf int8_t
wird.
Das type
kann nur auf die folgenden ganzzahligen Typen festgelegt werden:
-
byte
(8 Bit breit) -
int
(32 Bit breit) -
long
(64 Bit breit)
JavaOnlyStableParcelable
JavaOnlyStableParcelable
markiert eine parzellierbare Deklaration (nicht Definition) als stabil, sodass von anderen stabilen AIDL-Typen darauf verwiesen werden kann.
Stable AIDL erfordert, dass alle benutzerdefinierten Typen stabil sind. Für Parcelables erfordert die Stabilität, dass ihre Felder explizit in der AIDL-Quelldatei beschrieben sind.
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 nur deklariert) war, kann es nicht referenziert werden.
parcelable Data; // Data is NOT a structured parcelable
parcelable AnotherData {
Data d; // Error
}
JavaOnlyStableParcelable
können Sie die Prüfung außer Kraft setzen, 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
}
JavaAbgeleitet
JavaDerive
generiert automatisch Methoden für parzellierbare Typen im Java-Backend.
@JavaDerive(equals = true, toString = true)
parcelable Data {
int number;
String str;
}
Die Anmerkung erfordert zusätzliche Parameter, um zu steuern, was generiert werden soll. Die unterstützten Parameter sind:
-
equals=true
generiertequals
undhashCode
Methoden. -
toString=true
generiert dietoString
-Methode, die den Namen des Typs und der Felder ausgibt. Zum Beispiel:Data{number: 42, str: foo}
JavaDefault
JavaDefault
, das in Android 13 hinzugefügt wurde, steuert, ob die Unterstützung für die Standardversionsimplementierung generiert wird (für setDefaultImpl
). Diese Unterstützung wird standardmäßig nicht mehr generiert, um Platz zu sparen.
JavaPassthrough
JavaPassthrough
die generierte Java-API mit einer beliebigen Java-Annotation versehen 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 annotation
wird direkt ausgegeben. Der AIDL-Compiler untersucht den Wert des Parameters nicht. Wenn ein Syntaxfehler auf Java-Ebene auftritt, wird er nicht vom AIDL-Compiler, sondern vom Java-Compiler abgefangen.
Diese Anmerkung kann an jede AIDL-Entität angehängt werden. Diese Anmerkung ist ein No-Op für Nicht-Java-Back-Ends.
Feste Größe
FixedSize
markiert ein strukturiertes Paket als feste Größe. Nach der Markierung dürfen dem Parcelable keine neuen Felder hinzugefügt werden. Alle Felder der Parcelable müssen ebenfalls Typen mit fester Größe sein, einschließlich primitiver Typen, Aufzählungen, Arrays mit fester Größe und andere Parcelables, die mit FixedSize
gekennzeichnet sind.
Dies bietet keine Garantie für unterschiedliche Bitness und sollte nicht für die Kommunikation mit gemischter Bitness verwendet werden.
Beschreibung
Descriptor
gibt zwangsweise den Schnittstellendeskriptor einer Schnittstelle an.
package android.foo;
@Descriptor(value="android.bar.IWorld")
interface IHello {...}
Der Deskriptor der obigen Schnittstelle ist android.bar.IWorld
. Wenn die Descriptor
-Anmerkung fehlt, wäre der Descriptor android.foo.IHello
.
Dies 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.
@in Kommentaren verstecken
Der AIDL-Compiler erkennt @hide
in Kommentaren und leitet es an die Java-Ausgabe weiter, damit metalava es abholen kann. Dieser Kommentar stellt sicher, dass das Android-Buildsystem weiß, dass AIDL-APIs keine SDK-APIs sind.
@veraltet 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 markiert veraltete Entitäten mit einer Backend-spezifischen Anmerkung/einem Attribut, sodass der Client-Code gewarnt wird, wenn er auf die veralteten Entitäten verweist. Beispielsweise werden die Annotation @Deprecated
und das Tag @deprecated
an den von Java generierten Code angehängt.