AIDL mendukung anotasi yang memberikan info tambahan kepada compiler AIDL tentang elemen yang diberi anotasi, 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
entitas AIDL seperti interface Foo
, void method()
, atau int arg
. Anotasi
dilampirkan ke entitas 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 ditentukan sebelumnya. Beberapa anotasi hanya memengaruhi backend tertentu dan tidak beroperasi di backend lainnya. Keduanya memiliki batasan yang berbeda terkait tempat pemasangannya.
Berikut adalah daftar anotasi AIDL yang telah ditentukan 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
menyatakan bahwa nilai entitas yang diberi anotasi 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 adalah error.
void method(in @nullable int a); // int is a primitive type
Anotasi ini tidak beroperasi untuk backend Java. Hal ini karena, di Java, semua
jenis non-primitif diteruskan berdasarkan referensi, yang bisa 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 dipetakan ke std::optional<T>
.
Di backend Rust, @nullable T
selalu dipetakan ke Option<T>
.
Untuk jenis seperti daftar L
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 menggunakan backend CPP
untuk Android 11 atau yang lebih rendah).
Ada pengecualian untuk pemetaan ini. Jika T
adalah IBinder
atau antarmuka AIDL, @nullable
adalah no-op untuk semua backend kecuali
untuk Rust. Dengan kata lain, @nullable IBinder
dan IBinder
sama-sama dipetakan ke android::sp<IBinder>
, yang sudah dapat bernilai null karena merupakan pointer yang kuat (pembacaan CPP tetap menerapkan nullability, tetapi jenisnya tetap android::sp<IBinder>
). Di Rust, jenis ini adalah nullable
hanya jika dianotasi dengan @nullable
. Mereka dipetakan ke
Option<T>
jika diberi anotasi.
Mulai Android 13, @nullable(heap=true)
dapat digunakan untuk
kolom parcelable guna memodelkan jenis rekursif. @nullable(heap=true)
tidak dapat digunakan dengan parameter metode atau jenis nilai yang ditampilkan. Jika diberi anotasi, kolom akan dipetakan ke referensi yang dialokasikan heap std::unique_ptr<T>
di backend CPP/NDK. @nullable(heap=true)
adalah no-op di backend Java.
utf8InCpp
utf8InCpp
menyatakan bahwa String
ditampilkan dalam format UTF8 untuk backend CPP. Seperti namanya, anotasi ini tidak beroperasi untuk backend lain.
Secara khusus, String
selalu UTF16 di backend Java dan UTF8 di backend NDK.
Anotasi ini dapat dilampirkan di mana pun jenis String
dapat digunakan,
termasuk nilai yang ditampilkan, parameter, deklarasi konstanta, dan kolom
dapat di-parcel.
Untuk backend CPP, @utf8InCpp String
di AIDL dipetakan ke std::string
, sedangkan
String
tanpa anotasi dipetakan ke android::String16
tempat UTF16 digunakan.
Perhatikan bahwa keberadaan anotasi utf8InCpp
tidak mengubah cara string dikirimkan melalui jaringan. String selalu ditransmisikan sebagai UTF16
melalui jaringan. String beranotasi utf8InCpp
dikonversi ke UTF16 sebelum ditransmisikan. Saat diterima, string dikonversi dari UTF16 ke UTF8 jika
dianotasi sebagai utf8InCpp
.
VintfStability
VintfStability
menyatakan 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 sistem-vendor.
Anotasi tidak mengubah tanda tangan jenis, tetapi saat ditetapkan, instance jenis ditandai sebagai stabil sehingga dapat berpindah di seluruh proses vendor dan 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 dianotasi dengan VintfStability
, jenis lain yang direferensikan dalam jenis tersebut juga harus dianotasi seperti itu. Pada 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 diberi anotasi dengan VintfStability
hanya dapat dibangun menggunakan jenis modul Soong aidl_interface
, dengan
properti stability
disetel ke "vintf"
.
aidl_interface {
name: "my_interface",
srcs: [...],
stability: &
quot;vintf",
}
UnsupportedAppUsage
Anotasi UnsupportedAppUsage
menunjukkan bahwa jenis AIDL yang diberi anotasi adalah
bagian dari antarmuka non-SDK yang telah dapat diakses oleh aplikasi lama.
Lihat Pembatasan pada 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 no-op untuk backend non-Java.
Dukungan
Anotasi Backing
menentukan jenis penyimpanan jenis enum AIDL.
@Backing(type="int")
enum Color { RED
, BLUE, }
Di backend CPP, ini memancarkan class enum C++ berjenis int32_t
.
enum class Color : int32_t {
RED = 0,
BLUE = 1,
}
Jika anotasi tidak disertakan, type
diasumsikan sebagai byte
, yang dipetakan 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 (bukan definisi) parcelable
sebagai stabil sehingga dapat dirujuk dari jenis AIDL stabil lainnya. Hal 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, di sistem build inti pada modul
cc_*
, gunakanstatic_libs
ataushared_libs
. Untukaidl_interface
, tambahkan library di bagianadditional_shared_libraries
dalamAndroid.bp
.
JavaOnlyStableParcelable
JavaOnlyStableParcelable
menandai deklarasi (bukan definisi) parcelable
sebagai stabil sehingga dapat dirujuk dari jenis AIDL stabil lainnya.
AIDL Stabil mengharuskan semua jenis yang ditentukan pengguna bersifat 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 parcelable tidak dapat dirujuk.
parcelable Data; // Data is NOT a structured parcelable
parcelable AnotherData {
Data d; // Error
}
JavaOnlyStableParcelable
memungkinkan Anda mengganti pemeriksaan saat parcelable yang Anda referensikan sudah tersedia dengan aman sebagai bagian dari Android SDK.
@JavaOnlyStableParcelable
parcelable Data;
parcelable AnotherData {
Data d; // OK
}
JavaDerive
JavaDerive
secara otomatis membuat 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 dihasilkan. 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 dibuat (untuk
setDefaultImpl
). Dukungan ini tidak lagi dibuat secara default untuk
menghemat ruang.
JavaPassthrough
JavaPassthrough
memungkinkan Java API yang dihasilkan diberi anotasi dengan anotasi Java arbitrer.
Anotasi berikut di AIDL
@JavaPassthrough(annotation="@android.annotation.Alice")
@JavaPassthrough(annotation="@com.android.Alice(arg=com.android.Al
ice.Value.A)")
menjadi
@android.annotation.Alice
@com.android.Alice(arg=com.android.Alice.Value.A)
dalam kode Java yang dihasilkan.
Nilai parameter annotation
dipancarkan secara langsung. Kompiler
AIDL tidak melihat nilai parameter. Jika ada error sintaksis tingkat Java, error tersebut tidak akan terdeteksi oleh compiler AIDL, tetapi oleh compiler Java.
Anotasi ini dapat dilampirkan ke entitas AIDL mana pun. Anotasi ini tidak melakukan apa pun untuk backend non-Java.
RustDerive
RustDerive
otomatis menerapkan trait untuk jenis Rust yang dihasilkan.
Anotasi memerlukan parameter tambahan untuk mengontrol apa yang akan dihasilkan. Parameter yang didukung adalah:
Copy=true
Clone=true
Ord=true
PartialOrd=true
Eq=true
PartialEq=true
Hash=true
Untuk penjelasan tentang sifat ini, lihat https://doc.rust-lang.org.
FixedSize
FixedSize
menandai parcelable terstruktur sebagai ukuran tetap. Setelah ditandai, parcelable tidak akan diizinkan untuk menambahkan kolom baru ke dalamnya. Semua kolom
parcelable juga harus berupa jenis ukuran tetap, termasuk jenis primitif,
enum, array ukuran tetap, dan parcelable lain yang ditandai dengan FixedSize
.
Hal ini tidak memberikan jaminan apa pun di berbagai bitness dan tidak boleh diandalkan untuk komunikasi bitness campuran.
Deskripsi
Descriptor
secara paksa menentukan deskriptor antarmuka dari suatu antarmuka.
package android.foo;
@Descriptor(value="android.bar.IWorld")
interface IHe
llo {...}
Deskriptor 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. Membuat deskriptor antarmuka yang diganti namanya sama dengan deskriptor antarmuka sebelum penggantian nama memungkinkan kedua antarmuka berkomunikasi satu sama lain.
@hide dalam komentar
Compiler AIDL mengenali @hide
dalam komentar dan meneruskannya
ke output Java agar diambil oleh metalava. Komentar ini memastikan bahwa sistem build Android mengetahui bahwa AIDL API bukan SDK API.
@deprecated dalam komentar
Compiler AIDL mengenali @deprecated
dalam komentar sebagai tag untuk mengidentifikasi entitas AIDL yang tidak boleh 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 ke entity
yang tidak digunakan lagi. Misalnya, anotasi @Deprecated
dan tag @deprecated
dilampirkan ke kode yang dihasilkan Java.