El AIDL admite anotaciones que le brindan información adicional al compilador AIDL. sobre el elemento anotado, lo que también afecta el código de stub generado.
La sintaxis es similar a la de Java:
@AnnotationName(argument1=value, argument2=value) AidlEntity
Aquí, AnnotationName
es el nombre de la anotación, y AidlEntity
es
Una entidad de AIDL, como interface Foo
, void method()
o int arg
Los
se adjunta a la entidad que le sigue.
Algunas anotaciones pueden tener argumentos dentro de los paréntesis, como se muestra más arriba. Las anotaciones que no tienen un argumento no necesitan el paréntesis. Por ejemplo:
@AnnotationName AidlEntity
Estas anotaciones no son iguales a las de Java anotaciones, aunque se ven muy similares. Los usuarios no pueden definir AIDL personalizado anotaciones; las anotaciones están predefinidas. Algunas anotaciones solo afectan en un backend determinado y no funcionan en otros. Tienen diferentes restricciones a las que pueden adjuntarse.
Esta es la lista de anotaciones de AIDL predefinidas:
Anotaciones | Se agregó en la versión de Android |
---|---|
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
declara que no se puede proporcionar el valor de la entidad anotada.
Esta anotación solo se puede adjuntar a tipos de datos que se devuelven, parámetros de métodos, campos parcelables.
interface IFoo {
// method return types
@nullable Data method();
// method parameters
void method2(in @nullable Data d);
}
parcelable Data {
// parcelable fields
@nullable Data d;
}
No se pueden adjuntar anotaciones a los tipos primitivos. El siguiente es un error.
void method(in @nullable int a); // int is a primitive type
Esta anotación es no-op para el backend de Java. Esto se debe a que, en Java,
los tipos no primitivos se pasan por referencia, que podría ser null
.
En el backend de la CPP, @nullable T
se asigna a std::unique_ptr<T>
en Android
11 o versiones anteriores, y a std::optional<T>
en Android
12 o una versión posterior.
En el backend del NDK, @nullable T
siempre se asigna a std::optional<T>
.
Para un tipo similar a una lista, L
, como T[]
o List<T>
, @nullable L
se asigna a
std::optional<std::vector<std::optional<T>>>
(o
std::unique_ptr<std::vector<std::unique_ptr<T>>>
en el caso del backend de CPP
para Android 11 o versiones anteriores).
Hay una excepción a esta asignación. Cuando T
es IBinder
o una interfaz de AIDL, @nullable
es no-op. En otras palabras, tanto
@nullable IBinder
y IBinder
se asignan también a android::sp<IBinder>
, que
ya es anulable porque es un puntero sólido (el CPP lee aún
aplicar la nulabilidad, pero el tipo sigue siendo android::sp<IBinder>
).
A partir de Android 13, @nullable(heap=true)
se puede usar para
campos parcelables para modelar tipos recursivos. No se puede usar @nullable(heap=true)
con parámetros de métodos o tipos de datos que se devuelven. Cuando se anota con él, el campo se
Se asignó a una referencia std::unique_ptr<T>
asignada por el montón en el CPP/NDK
backends. @nullable(heap=true)
es no-op en el backend de Java.
utf8InCpp
utf8InCpp
declara que un String
se representa en formato UTF8 para el CPP.
backend. Como su nombre lo indica, la anotación es una no-op para otros backends.
Específicamente, String
siempre es UTF16 en el backend de Java y UTF8 en el NDK
backend.
Esta anotación se puede adjuntar siempre que se pueda usar el tipo String
.
incluidos valores que se devuelven, parámetros, declaraciones de constantes y valores
.
Para el backend de la CPP, @utf8InCpp String
en el AIDL se asigna a std::string
, mientras que
String
sin la anotación se asigna a android::String16
, donde se usa UTF16.
Ten en cuenta que la existencia de la anotación utf8InCpp
no cambia la forma en que
las cadenas se transmiten por cable. Las cadenas siempre se transmiten como UTF16.
por el cable. Una cadena con anotaciones utf8InCpp
se convierte a UTF16 antes de
transmitirse. Cuando se recibe una cadena, se convierte de UTF16 a UTF8 si
se anotó como utf8InCpp
.
VintfStability
VintfStability
declara que un tipo definido por el usuario (interfaz, parcelable,
y enum) se pueden usar en los dominios del sistema y del proveedor. Consulta
AIDL para HALs para obtener más información sobre
interoperabilidad entre sistemas y proveedores.
La anotación no cambia la firma del tipo, pero cuando se establece, la instancia del tipo se marca como estable para que pueda viajar los procesos del proveedor y del sistema.
La anotación solo se puede adjuntar a declaraciones de tipo definidas por el usuario, como se muestra a continuación aquí:
@VintfStability
interface IFoo {
....
}
@VintfStability
parcelable Data {
....
}
@VintfStability
enum Type {
....
}
Cuando un tipo se anota con VintfStability
, cualquier otro tipo que se
a las que se hace referencia en el tipo también deberían anotarse como tales. En la siguiente
Por ejemplo, Data
y IBar
deberían tener anotaciones con 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 {...}
Además, los archivos AIDL que definen tipos con anotaciones VintfStability
solo se pueden compilar con el tipo de módulo aidl_interface
de Soong, con el
La propiedad stability
se estableció en "vintf"
.
aidl_interface {
name: "my_interface",
srcs: [...],
stability: "vintf",
}
Uso de la aplicación no admitido
La anotación UnsupportedAppUsage
indica que el tipo de AIDL anotado es
parte de la interfaz que no pertenece al SDK y a la que pueden acceder las apps heredadas.
Consulta Restricciones en el SDK que no pertenece al SDK.
interfaces
para obtener más información sobre las APIs ocultas.
La anotación UnsupportedAppUsage
no afecta el comportamiento de la
código generado. La anotación solo anota la clase Java generada con el
Anotación Java del mismo nombre.
// in AIDL
@UnsupportedAppUsage
interface IFoo {...}
// in Java
@android.compat.annotation.UnsupportedAppUsage
public interface IFoo {...}
Esta es una no-op para backends que no son de Java.
Copia de seguridad
La anotación Backing
especifica el tipo de almacenamiento de un tipo de enumeración del AIDL.
@Backing(type="int")
enum Color { RED, BLUE, }
En el backend de la CPP, se emite una clase enum C++ de tipo int32_t
.
enum class Color : int32_t {
RED = 0,
BLUE = 1,
}
Si se omite la anotación, se supone que type
es byte
, lo cual
en int8_t
para el backend de CPP.
El argumento type
solo se puede establecer en los siguientes tipos de integrales:
byte
(ancho de 8 bits)int
(ancho de 32 bits)long
(ancho de 64 bits)
NdkOnlyStableParcelable
NdkOnlyStableParcelable
marca una declaración parcelable (sin definición).
como estable para que se pueda hacer referencia desde otros tipos de AIDL estables. Esta
es como JavaOnlyStableParcelable
, pero
NdkOnlyStableParcelable
marca una declaración parcelable como estable para el NDK.
backend en lugar de para Java.
Para usar este objeto parcelable:
- Debes especificar
ndk_header
. - Debes tener una biblioteca de NDK que especifique el elemento parcelable, y la biblioteca
compilarse en la biblioteca. Por ejemplo, en el sistema de compilación central en un
cc_*
, usastatic_libs
oshared_libs
. Paraaidl_interface
, agrega la biblioteca deadditional_shared_libraries
enAndroid.bp
.
JavaOnlyStableParcelable
JavaOnlyStableParcelable
marca una declaración parcelable (sin definición).
como estable para que se pueda hacer referencia desde otros tipos de AIDL estables.
El AIDL estable requiere que todos los tipos definidos por el usuario sean estables. Para parcelables, ser estable requiere que sus campos se describan explícitamente en en el archivo fuente de 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
}
Si el objeto parcelable no era estructurado (o se declaró recientemente), no se puede a los que se hace referencia.
parcelable Data; // Data is NOT a structured parcelable
parcelable AnotherData {
Data d; // Error
}
JavaOnlyStableParcelable
te permite anular la comprobación cuando el elemento
a los que haces referencia ya está disponible de forma segura como parte del SDK de Android.
@JavaOnlyStableParcelable
parcelable Data;
parcelable AnotherData {
Data d; // OK
}
JavaDerive
JavaDerive
genera automáticamente métodos para tipos parcelables en el
Backend de Java.
@JavaDerive(equals = true, toString = true)
parcelable Data {
int number;
String str;
}
La anotación requiere parámetros adicionales para controlar qué generar. Los parámetros admitidos son los siguientes:
equals=true
genera los métodosequals
yhashCode
.toString=true
genera el métodotoString
que imprime el nombre del tipo. y campos específicos. Por ejemplo:Data{number: 42, str: foo}
JavaDefault
JavaDefault
, que se agregó en Android 13, controla si
se genera la compatibilidad predeterminada con el control de versiones para la implementación (para
setDefaultImpl
). Esta compatibilidad ya no se genera de forma predeterminada para
y ahorrar espacio.
JavaPassthrough
JavaPassthrough
permite que la API de Java generada se anote con una anotación
anotación de Java.
Las siguientes anotaciones en el AIDL
@JavaPassthrough(annotation="@android.annotation.Alice")
@JavaPassthrough(annotation="@com.android.Alice(arg=com.android.Alice.Value.A)")
convertirse en
@android.annotation.Alice
@com.android.Alice(arg=com.android.Alice.Value.A)
en el código Java generado.
El valor del parámetro annotation
se emite directamente. El AIDL
el compilador no analiza el valor del parámetro. Si hay alguna
Error de sintaxis a nivel de Java, no será detectado por el compilador del AIDL, sino por el
Compilador de Java.
Esta anotación se puede adjuntar a cualquier entidad de AIDL. Esta anotación es no-op para backends que no son de Java.
Tamaño fijo
FixedSize
marca un objeto parcelable estructurado como tamaño fijo. Una vez que las marcas,
parcelable no tendrá permisos que se le agreguen campos nuevos. Todos los campos de
el parcelable también deben ser de tipo fijo, incluidos los tipos primitivos,
enumeraciones, arrays de tamaño fijo y otros objetos parcelables marcados con FixedSize
.
Esto no proporciona ninguna garantía en diferentes bits de datos y no debería de las que dependía para una comunicación mixta.
Descriptor
Descriptor
especifica de manera forzosa el descriptor de interfaz de una interfaz.
package android.foo;
@Descriptor(value="android.bar.IWorld")
interface IHello {...}
El descriptor de esta interfaz es android.bar.IWorld
. Si el botón
Falta la anotación Descriptor
, el descriptor sería
android.foo.IHello
Esto es útil para cambiar el nombre de una interfaz ya publicada. Hacer que el descriptor de la interfaz a la que le cambiaste el nombre de la misma manera que el descriptor de la interfaz antes del cambio de nombre permite que las dos interfaces se comuniquen entre sí.
@ocultar en los comentarios
El compilador de AIDL reconoce @hide
en los comentarios y lo pasa por
a la salida de Java para que metalava recoja. Este comentario garantiza que el código
de compilación reconoce que las APIs de AIDL no son APIs del SDK.
@obsoleto en los comentarios
El compilador de AIDL reconoce @deprecated
en los comentarios como una etiqueta para identificar un
Es la entidad de AIDL que ya no se debe usar.
interface IFoo {
/** @deprecated use bar() instead */
void foo();
void bar();
}
Cada backend marca las entidades obsoletas con una anotación específica de backend o
para que el código del cliente reciba una advertencia si hace referencia al atributo obsoleto
entidades. Por ejemplo, la anotación @Deprecated
y @deprecated
etiqueta de estado se adjuntan al código Java generado.