AIDL mendukung anotasi yang memberikan info tambahan kepada compiler AIDL tentang elemen yang dianotasi, yang juga memengaruhi kode stub yang dihasilkan.
Sintaksisnya mirip dengan Java:
@AnnotationName(argument1=value, argument2=value) AidlEntity
Di sini, AnnotationName
adalah nama anotasi, dan AidlEntity
adalah
entity AIDL seperti interface Foo
, void method()
, atau int arg
. Anotasi
akan dilampirkan ke entity yang mengikutinya.
Beberapa anotasi dapat memiliki argumen yang ditetapkan di dalam tanda kurung, seperti yang ditunjukkan di atas. Anotasi yang tidak memiliki argumen tidak memerlukan tanda kurung. Contoh:
@AnnotationName AidlEntity
Anotasi ini tidak sama dengan anotasi Java, meskipun terlihat sangat mirip. Pengguna tidak dapat menentukan anotasi AIDL kustom; semua anotasi telah ditetapkan sebelumnya. Beberapa anotasi hanya memengaruhi backend tertentu dan tidak memiliki pengoperasian di backend lainnya. Keduanya memiliki batasan yang berbeda-beda.
Berikut adalah daftar anotasi AIDL yang telah ditetapkan sebelumnya:
Anotasi | Ditambahkan di versi 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
mendeklarasikan bahwa nilai entity yang dianotasi mungkin tidak diberikan.
Anotasi ini hanya dapat dilampirkan ke jenis nilai yang ditampilkan metode, parameter metode, dan kolom parcelable.
interface IFoo {
// method return types
@nullable Data method();
// method parameters
void method2(in @nullable Data d);
}
parcelable Data {
// parcelable fields
@nullable Data d;
}
Anotasi tidak dapat dilampirkan ke jenis primitif. Berikut ini adalah error.
void method(in @nullable int a); // int is a primitive type
Anotasi ini tidak memiliki pengoperasian untuk backend Java. Hal ini karena di Java, semua jenis non-primitif diteruskan melalui referensi, yang dapat berupa null
.
Di backend CPP, @nullable T
dipetakan ke std::unique_ptr<T>
di Android
11 atau yang lebih rendah, dan ke std::optional<T>
di Android
12 atau yang lebih tinggi.
Di backend NDK, @nullable T
selalu memetakan ke std::optional<T>
.
Untuk jenis L
seperti daftar seperti T[]
atau List<T>
, @nullable L
dipetakan ke
std::optional<std::vector<std::optional<T>>>
(atau
std::unique_ptr<std::vector<std::unique_ptr<T>>>
jika backend CPP
untuk Android 11 atau yang lebih rendah).
Ada pengecualian untuk pemetaan ini. Jika T
adalah IBinder
atau antarmuka AIDL, @nullable
tidak memiliki operasi. Dengan kata lain, @nullable IBinder
dan IBinder
sama-sama dipetakan ke android::sp<IBinder>
, yang
sudah nullable karena merupakan pointer yang kuat (pembaca CPP masih
menerapkan nullability, tetapi jenisnya masih android::sp<IBinder>
).
Mulai Android 13, @nullable(heap=true)
dapat digunakan untuk
kolom yang dapat dibagikan guna memodelkan jenis rekursif. @nullable(heap=true)
tidak dapat digunakan
dengan parameter metode atau jenis nilai yang ditampilkan. Jika dianotasikan, kolom ini
dipetakan ke referensi dengan alokasi heap std::unique_ptr<T>
di backend
CPP/NDK. @nullable(heap=true)
tidak memiliki pengoperasian di backend Java.
{i>utf8InCpp<i}
utf8InCpp
mendeklarasikan bahwa String
direpresentasikan dalam format UTF8 untuk backend
CPP. Seperti namanya, anotasi ini merupakan tanpa pengoperasian untuk backend lainnya.
Secara khusus, String
selalu berupa UTF16 di backend Java dan UTF8 di backend
NDK.
Anotasi ini dapat disertakan di mana pun jenis String
dapat digunakan,
termasuk nilai yang ditampilkan, parameter, deklarasi konstanta, dan kolom
parcelable.
Untuk backend CPP, @utf8InCpp String
di AIDL dipetakan ke std::string
, sedangkan
String
tanpa anotasi dipetakan ke android::String16
tempat UTF16 digunakan.
Perlu diperhatikan bahwa keberadaan anotasi utf8InCpp
tidak mengubah cara
string ditransmisikan melalui kabel. String selalu ditransmisikan sebagai UTF16
melalui kabel. String beranotasi utf8InCpp
dikonversi ke UTF16 sebelum
dikirim. Saat diterima, string akan dikonversi dari UTF16 ke UTF8 jika
dianotasi sebagai utf8InCpp
.
Kestabilan
VintfStability
mendeklarasikan bahwa jenis yang ditentukan pengguna (antarmuka, parcelable, dan enum) dapat digunakan di seluruh domain sistem dan vendor. Lihat
AIDL untuk HAL untuk mengetahui informasi selengkapnya tentang
interoperabilitas vendor sistem.
Anotasi tidak mengubah tanda tangan jenis, tetapi saat ditetapkan, instance jenis ditandai sebagai stabil sehingga dapat berpindah lintas vendor dan proses sistem.
Anotasi hanya dapat dilampirkan ke deklarasi jenis yang ditentukan pengguna seperti yang ditunjukkan di sini:
@VintfStability
interface IFoo {
....
}
@VintfStability
parcelable Data {
....
}
@VintfStability
enum Type {
....
}
Jika suatu jenis dianotasikan dengan VintfStability
, jenis lain apa pun yang
direferensikan dalam jenis tersebut juga harus dianotasi sedemikian rupa. Dalam contoh
berikut, Data
dan IBar
harus dianotasi dengan 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 {...}
Selain itu, file AIDL yang menentukan jenis yang dianotasikan dengan VintfStability
hanya dapat dibuat menggunakan jenis modul aidl_interface
Soong, dengan
properti stability
ditetapkan ke "vintf"
.
aidl_interface {
name: "my_interface",
srcs: [...],
stability: "vintf",
}
PenggunaanAplikasi yang Tidak Didukung
Anotasi UnsupportedAppUsage
menunjukkan bahwa jenis AIDL yang dianotasi adalah
bagian dari antarmuka non-SDK yang telah dapat diakses untuk aplikasi lama.
Lihat Pembatasan antarmuka
non-SDK
untuk mengetahui informasi selengkapnya tentang API tersembunyi.
Anotasi UnsupportedAppUsage
tidak memengaruhi perilaku
kode yang dihasilkan. Anotasi hanya menganotasi class Java yang dihasilkan dengan
anotasi Java dengan nama yang sama.
// in AIDL
@UnsupportedAppUsage
interface IFoo {...}
// in Java
@android.compat.annotation.UnsupportedAppUsage
public interface IFoo {...}
Ini adalah kondisi tanpa pengoperasian untuk backend non-Java.
Pendukung
Anotasi Backing
menentukan jenis penyimpanan jenis enum AIDL.
@Backing(type="int")
enum Color { RED, BLUE, }
Di backend CPP, class ini memunculkan class enum C++ jenis int32_t
.
enum class Color : int32_t {
RED = 0,
BLUE = 1,
}
Jika anotasi dihilangkan, type
diasumsikan sebagai byte
, yang memetakan
ke int8_t
untuk backend CPP.
Argumen type
hanya dapat ditetapkan ke jenis integral berikut:
byte
(lebar 8 bit)int
(lebar 32-bit)long
(lebar 64-bit)
NdkOnlyStableParcelable
NdkOnlyStableParcelable
menandai deklarasi parcelable (bukan definisi)
sebagai stabil sehingga dapat direferensikan dari jenis AIDL stabil lainnya. Ini
seperti JavaOnlyStableParcelable
, tetapi
NdkOnlyStableParcelable
menandai deklarasi parcelable sebagai stabil untuk backend
NDK, bukan untuk Java.
Untuk menggunakan parcelable ini:
- Anda harus menentukan
ndk_header
. - Anda harus memiliki library NDK yang menentukan parcelable dan library harus
dikompilasi ke dalam library. Misalnya, dalam sistem build inti pada
modul
cc_*
, gunakanstatic_libs
ataushared_libs
. Untukaidl_interface
, tambahkan library di bagianadditional_shared_libraries
diAndroid.bp
.
JavaOnlyStableParcelable
JavaOnlyStableParcelable
menandai deklarasi parcelable (bukan definisi)
sebagai stabil sehingga dapat direferensikan dari jenis AIDL stabil lainnya.
AIDL stabil mengharuskan semua jenis yang ditentukan pengguna stabil. Untuk parcelable, agar stabil, kolomnya harus dijelaskan secara eksplisit dalam file sumber 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
}
Jika parcelable tidak terstruktur (atau hanya dideklarasikan), maka tidak dapat direferensikan.
parcelable Data; // Data is NOT a structured parcelable
parcelable AnotherData {
Data d; // Error
}
JavaOnlyStableParcelable
memungkinkan Anda mengganti pemeriksaan jika parcelable
yang Anda referensikan sudah tersedia dengan aman sebagai bagian dari Android SDK.
@JavaOnlyStableParcelable
parcelable Data;
parcelable AnotherData {
Data d; // OK
}
JavaDerive
JavaDerive
otomatis menghasilkan metode untuk jenis parcelable di
backend Java.
@JavaDerive(equals = true, toString = true)
parcelable Data {
int number;
String str;
}
Anotasi memerlukan parameter tambahan untuk mengontrol apa yang akan dibuat. Parameter yang didukung adalah:
equals=true
menghasilkan metodeequals
danhashCode
.toString=true
menghasilkan metodetoString
yang mencetak nama jenis dan kolom. Contoh:Data{number: 42, str: foo}
JavaDefault
JavaDefault
, yang ditambahkan di Android 13, mengontrol apakah
dukungan pembuatan versi implementasi default akan dihasilkan (untuk
setDefaultImpl
). Dukungan ini tidak lagi dihasilkan secara default untuk
menghemat ruang penyimpanan.
JavaPassthrough
JavaPassthrough
memungkinkan API Java yang dihasilkan dianotasi dengan anotasi
Java arbitrer.
Anotasi berikut di AIDL
@JavaPassthrough(annotation="@android.annotation.Alice")
@JavaPassthrough(annotation="@com.android.Alice(arg=com.android.Alice.Value.A)")
menjadi
@android.annotation.Alice
@com.android.Alice(arg=com.android.Alice.Value.A)
dalam kode Java yang dihasilkan.
Nilai parameter annotation
langsung ditampilkan. Compiler AIDL tidak memeriksa nilai parameter. Jika terjadi
error sintaksis tingkat Java, error tersebut tidak akan ditangkap oleh compiler AIDL, tetapi
oleh compiler Java.
Anotasi ini dapat disertakan ke entitas AIDL mana pun. Anotasi ini adalah operasi tanpa pengoperasian untuk backend non-Java.
Ukuran Tetap
FixedSize
menandai parcelable terstruktur sebagai ukuran tetap. Setelah ditandai, parcelable tidak akan diizinkan untuk ditambahkan ke kolom baru. Semua kolom parcelable juga harus berupa jenis berukuran tetap, termasuk jenis primitif, enum, array ukuran tetap, dan parcelable lainnya yang ditandai dengan FixedSize
.
Hal ini tidak memberikan jaminan di berbagai bitness dan tidak boleh diandalkan untuk komunikasi campuran bit.
Deskripsi
Descriptor
secara paksa menentukan deskriptor antarmuka antarmuka.
package android.foo;
@Descriptor(value="android.bar.IWorld")
interface IHello {...}
Deskripsi antarmuka ini adalah android.bar.IWorld
. Jika
anotasi Descriptor
tidak ada, deskriptornya adalah
android.foo.IHello
.
Hal ini berguna untuk mengganti nama antarmuka yang sudah dipublikasikan. Dengan menjadikan deskriptor antarmuka yang diganti namanya sama dengan deskriptor antarmuka sebelum penggantian nama tersebut, kedua antarmuka ini dapat saling berkomunikasi.
@sembunyikan di komentar
Compiler AIDL mengenali @hide
dalam komentar dan meneruskannya melalui
output Java untuk metalava yang akan diambil. Komentar ini memastikan bahwa sistem build Android
mengetahui bahwa AIDL API bukanlah SDK API.
@tidak digunakan lagi di komentar
Compiler AIDL mengenali @deprecated
dalam komentar sebagai tag untuk mengidentifikasi
entity AIDL yang sebaiknya tidak digunakan lagi.
interface IFoo {
/** @deprecated use bar() instead */
void foo();
void bar();
}
Setiap backend menandai entity yang tidak digunakan lagi dengan anotasi atau
atribut khusus backend, sehingga kode klien akan diperingatkan jika merujuk entitas
yang tidak digunakan lagi. Misalnya, anotasi @Deprecated
dan tag @deprecated
dilampirkan ke kode yang dihasilkan Java.