A AIDL oferece suporte a anotações que dão ao compilador AIDL informações extras sobre o elemento anotado, o que também afeta o código stub gerado.
A sintaxe é semelhante à do Java:
@AnnotationName(argument1=value, argument2=value) AidlEntity
Aqui, AnnotationName
é o nome da anotação e AidlEntity
é
uma entidade AIDL, como interface Foo
, void method()
ou int arg
. Um
é anexada à entidade que a segue.
Algumas anotações podem ter argumentos definidos entre parênteses, como mostrado acima. Anotações que não têm um argumento não precisam de parênteses. Exemplo:
@AnnotationName AidlEntity
Essas anotações não são iguais às anotações, embora sejam muito semelhantes. Os usuários não podem definir a AIDL personalizada anotações todas as anotações são predefinidas. Algumas anotações afetam apenas de um determinado back-end e são autônomos em outros. Eles têm diferentes restrições em que podem ser anexados.
Confira a lista de anotações AIDL predefinidas:
Anotações | Adicionado à versão do 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 |
anulável
nullable
declara que o valor da entidade anotada pode não ser fornecido.
Essa anotação só pode ser anexada a tipos de retorno, parâmetros de método e parcelable.
interface IFoo {
// method return types
@nullable Data method();
// method parameters
void method2(in @nullable Data d);
}
parcelable Data {
// parcelable fields
@nullable Data d;
}
Anotações não podem ser anexadas a tipos primitivos. Veja a seguir um erro.
void method(in @nullable int a); // int is a primitive type
Essa anotação não opera para o back-end Java. Isso porque, em Java,
tipos não primitivos são transmitidos por referência, que pode ser null
.
No back-end do CPP, @nullable T
é mapeado para std::unique_ptr<T>
no Android.
11 ou anterior e para std::optional<T>
no Android
12 ou superior.
No back-end do NDK, @nullable T
sempre é mapeado para std::optional<T>
.
Para um tipo de lista L
, como T[]
ou List<T>
, @nullable L
é mapeado para
std::optional<std::vector<std::optional<T>>>
(ou
std::unique_ptr<std::vector<std::unique_ptr<T>>>
no caso do back-end de CPP
para o Android 11 ou versões anteriores).
Há uma exceção nesse mapeamento. Quando T
é IBinder
ou uma interface AIDL, @nullable
é um ambiente autônomo. Em outras palavras, tanto
@nullable IBinder
e IBinder
mapeiam igualmente para android::sp<IBinder>
, que
já é anulável porque é um ponteiro forte (o CPP lê
aplicar a nulidade, mas o tipo ainda é android::sp<IBinder>
).
A partir do Android 13, a @nullable(heap=true)
pode ser usada para
Campos parcelable para modelar tipos recursivos. Não é possível usar @nullable(heap=true)
com parâmetros de método ou tipos de retorno. Quando anotado com ele, o campo é
mapeado para uma referência std::unique_ptr<T>
alocada por heap no CPP/NDK
back-ends de aplicativos. @nullable(heap=true)
é um ambiente autônomo no back-end Java.
utf8InCpp
utf8InCpp
declara que um String
é representado no formato UTF8 para o CPP.
back-end. Como o nome indica, a anotação é um ambiente autônomo para outros back-ends.
Especificamente, String
é sempre UTF16 no back-end do Java e UTF8 no NDK.
back-end.
Essa anotação pode ser anexada em qualquer lugar em que o tipo String
possa ser usado.
incluindo valores de retorno, parâmetros, declarações constantes e parcelable
campos.
Para o back-end do CPP, @utf8InCpp String
na AIDL é mapeado para std::string
, enquanto
String
sem a anotação é mapeado para android::String16
, em que UTF16 é usado.
A existência da anotação utf8InCpp
não muda a maneira como
as strings são transmitidas pelos fios. Strings sempre são transmitidas como UTF16
pelos fios. Uma string com a anotação utf8InCpp
é convertida em UTF16 antes de ser
transmitidos. Quando uma string é recebida, ela é convertida de UTF16 para UTF8,
foi anotado como utf8InCpp
.
VintfStability
VintfStability
declara que um tipo definido pelo usuário (interface, parcelable,
e enum) podem ser usadas nos domínios do sistema e do fornecedor. Consulte
AIDL para HALs para saber mais sobre
e a interoperabilidade
entre sistema e fornecedor.
A anotação não altera a assinatura do tipo, mas, quando é definida, a instância do tipo é marcada como estável para que possa viajar do fornecedor e dos processos do sistema.
A anotação só pode ser anexada a declarações de tipo definidas pelo usuário, conforme mostrado aqui:
@VintfStability
interface IFoo {
....
}
@VintfStability
parcelable Data {
....
}
@VintfStability
enum Type {
....
}
Quando um tipo é anotado com VintfStability
, qualquer outro tipo que seja
referenciados no tipo também precisam ser anotados dessa forma. Nos seguintes
exemplo, Data
e IBar
precisam ser anotados com 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 {...}
Além disso, os arquivos AIDL que definem os tipos anotados com VintfStability
só pode ser criado usando o tipo de módulo Soong aidl_interface
, com o
A propriedade stability
foi definida como "vintf"
.
aidl_interface {
name: "my_interface",
srcs: [...],
stability: "vintf",
}
Uso não aceito no app
A anotação UnsupportedAppUsage
indica que o tipo AIDL com anotação é
parte da interface externa ao SDK acessível a apps legados.
Consulte Restrições para produtos que não são do SDK
interfaces
para mais informações sobre as APIs ocultas.
A anotação UnsupportedAppUsage
não afeta o comportamento do
código gerado. A anotação anota apenas a classe Java gerada com o
Java com o mesmo nome.
// in AIDL
@UnsupportedAppUsage
interface IFoo {...}
// in Java
@android.compat.annotation.UnsupportedAppUsage
public interface IFoo {...}
Este é um ambiente autônomo para back-ends não Java.
Apoio
A anotação Backing
especifica o tipo de armazenamento de um tipo de enumeração AIDL.
@Backing(type="int")
enum Color { RED, BLUE, }
No back-end do CPP, isso emite uma classe de enumeração C++ do tipo int32_t
.
enum class Color : int32_t {
RED = 0,
BLUE = 1,
}
Se a anotação for omitida, o type
será considerado byte
, que mapeia
para int8_t
no back-end de CPP.
O argumento type
pode ser definido apenas para os seguintes tipos de integrais:
byte
(8 bits de largura)int
(32 bits de largura)long
(64 bits de largura)
NdkOnlyStableParcelable
NdkOnlyStableParcelable
marca uma declaração fracionável (não definição).
como estável para que possa ser referenciado de outros tipos de AIDL estáveis. Isso
é como JavaOnlyStableParcelable
, mas
NdkOnlyStableParcelable
marca uma declaração parcelable como estável para o NDK.
em vez de para Java.
Para usar o parcelable:
- É necessário especificar
ndk_header
. - Você precisa ter uma biblioteca do NDK especificando o parcelable, e a biblioteca precisa
ser compilado na biblioteca. Por exemplo, no sistema de build principal em um
cc_*
, usestatic_libs
oushared_libs
. Paraaidl_interface
, adicione a biblioteca emadditional_shared_libraries
emAndroid.bp
.
JavaOnlyStableParcelable
JavaOnlyStableParcelable
marca uma declaração fracionável (não definição).
como estável para que possa ser referenciado de outros tipos de AIDL estáveis.
A AIDL estável exige que todos os tipos definidos pelo usuário sejam estáveis. Para parcelables, a estabilidade requer que os campos sejam descritos explicitamente em o arquivo de origem 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
}
Se o parcelable não foi estruturado (ou acabou de ser declarado), ele não poderá ser referenciadas.
parcelable Data; // Data is NOT a structured parcelable
parcelable AnotherData {
Data d; // Error
}
JavaOnlyStableParcelable
permite substituir a verificação quando o parcelable
já está disponível com segurança como parte do SDK do Android.
@JavaOnlyStableParcelable
parcelable Data;
parcelable AnotherData {
Data d; // OK
}
JavaDerive
O JavaDerive
gera automaticamente métodos para tipos fracionáveis no
back-end do Java.
@JavaDerive(equals = true, toString = true)
parcelable Data {
int number;
String str;
}
A anotação requer parâmetros adicionais para controlar o que gerar. Os parâmetros aceitos são:
equals=true
gera os métodosequals
ehashCode
.toString=true
gera um métodotoString
que mostra o nome do tipo e campos. Por exemplo:Data{number: 42, str: foo}
Padrão Java
A JavaDefault
, adicionada no Android 13, controla se
o suporte de controle de versão de implementação padrão é gerado (para
setDefaultImpl
). Esse suporte não é mais gerado por padrão para
para economizar espaço.
JavaPassthrough
JavaPassthrough
permite que a API Java gerada seja anotada com uma anotação
Anotação Java.
As seguintes anotações na AIDL
@JavaPassthrough(annotation="@android.annotation.Alice")
@JavaPassthrough(annotation="@com.android.Alice(arg=com.android.Alice.Value.A)")
se tornar
@android.annotation.Alice
@com.android.Alice(arg=com.android.Alice.Value.A)
no código Java gerado.
O valor do parâmetro annotation
é emitido diretamente. A AIDL
não analisa o valor do parâmetro. Se houver
Erro de sintaxe no nível do Java, não será capturado pelo compilador AIDL, mas pelo
Compilador Java.
Essa anotação pode ser anexada a qualquer entidade AIDL. Esta anotação é um ambiente autônomo para back-ends não Java.
Tamanho fixo
FixedSize
marca um parcelable estruturado como tamanho fixo. Uma vez marcada, a
A parcelable não poderá ter novos campos adicionados a ela. Todos os campos de
o parcelable também precisa ter tipos de tamanho fixos, incluindo tipos primitivos,
tipos enumerados, matrizes de tamanho fixo e outros parcelables marcados com FixedSize
.
Isso não fornece nenhuma garantia para diferentes bits e não deve ser muito usados para comunicação de bits mistas.
Descritor
Descriptor
especifica à força o descritor de uma interface.
package android.foo;
@Descriptor(value="android.bar.IWorld")
interface IHello {...}
O descritor dessa interface é android.bar.IWorld
. Se o
A anotação Descriptor
está ausente. O descritor seria:
android.foo.IHello
.
Isso é útil para renomear uma interface já publicada. Fazer o descritor da interface renomeada igual ao descritor da interface antes da renomeação permite que as duas interfaces se comuniquem.
@ocultar nos comentários
O compilador AIDL reconhece @hide
nos comentários e o transmite
para saída Java para metalava para retirada. Esse comentário garante que o ambiente
sistema de build sabe que as APIs AIDL não são APIs do SDK.
@descontinuado nos comentários
O compilador AIDL reconhece @deprecated
nos comentários como uma tag para identificar uma
Entidade AIDL que não deve mais ser usada.
interface IFoo {
/** @deprecated use bar() instead */
void foo();
void bar();
}
Cada back-end marca as entidades descontinuadas com uma anotação específica do back-end ou
para que o código do cliente seja avisado caso se refira à
entidades. Por exemplo, a anotação @Deprecated
e o @deprecated
são anexadas ao código gerado em Java.