AIDL mendukung anotasi yang memberi kompiler AIDL info tambahan tentang elemen beranotasi, yang juga memengaruhi kode rintisan yang dihasilkan.
Sintaksnya mirip dengan Java:
@AnnotationName(argument1=value, argument2=value) AidlEntity
Di sini, AnnotationName
adalah nama dari anotasi, dan AidlEntity
adalah entitas AIDL seperti interface Foo
, void method()
, atau int arg
. Sebuah anotasi dilampirkan ke entitas yang mengikutinya.
Beberapa anotasi dapat memiliki argumen yang diatur di dalam tanda kurung, seperti yang ditunjukkan di atas. Anotasi yang tidak memiliki argumen tidak memerlukan tanda kurung. Sebagai contoh:
@AnnotationName AidlEntity
Anotasi ini tidak sama dengan anotasi Java, meskipun terlihat sangat mirip. Pengguna tidak dapat menentukan anotasi AIDL khusus; semua anotasi telah ditentukan sebelumnya. Beberapa anotasi hanya memengaruhi backend tertentu dan tidak berfungsi di backend lain. Mereka memiliki batasan yang berbeda di mana mereka dapat dilampirkan.
Di bawah ini adalah daftar anotasi AIDL yang telah ditentukan sebelumnya:
Anotasi | Ditambahkan dalam versi Android |
---|---|
nullable | 7 |
utf8InCpp | 7 |
VintfStability | 11 |
UnsupportedAppUsage | 10 |
Hide | 11 |
Backing | 11 |
JavaOnlyStableParcelable | 11 |
JavaDerive | 12 |
JavaPassthrough | 12 |
FixedSize | 12 |
Descriptor | 12 |
tidak dapat dibatalkan
nullable
menyatakan bahwa nilai entitas beranotasi tidak dapat diberikan.
Anotasi ini hanya dapat dilampirkan ke jenis pengembalian metode, parameter metode, dan bidang yang dapat dibagi.
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 tipe primitif. Berikut ini adalah kesalahan.
void method(in @nullable int a); // int is a primitive type
Anotasi ini tidak cocok untuk backend Java. Ini karena, di Jawa, semua tipe non-primitif dilewatkan dengan referensi, yang bisa berupa null
.
Di backend CPP, @nullable T
memetakan ke std::unique_ptr<T>
di Android 11 atau lebih rendah, dan ke std::optional<T>
di Android 12 atau lebih tinggi.
Di backend NDK, @nullable T
selalu memetakan ke std::optional<T>
.
Untuk tipe L
seperti daftar seperti T[]
atau List<T>
, @nullable L
memetakan ke std::optional<std::vector<std::optional<T>>>
(atau std::unique_ptr<std::vector<std::unique_ptr<T>>>
dalam hal backend CPP untuk Android 11 atau lebih rendah).
Ada pengecualian untuk pemetaan ini. Ketika T
adalah IBinder
atau antarmuka AIDL, @nullable
adalah no-op. Dengan kata lain, baik @nullable IBinder
dan IBinder
sama-sama memetakan ke android::sp<IBinder>
, yang sudah nullable karena merupakan pointer yang kuat (pembacaan CPP masih memberlakukan nullability, tetapi tipenya masih android::sp<IBinder>
).
Dimulai dengan Android T (AOSP eksperimental), @nullable(heap=true)
dapat digunakan untuk bidang parcelable untuk memodelkan jenis rekursif. @nullable(heap=true)
tidak dapat digunakan dengan parameter metode atau tipe pengembalian. Saat dianotasi dengannya, bidang dipetakan ke referensi yang dialokasikan heap std::unique_ptr<T>
di backend CPP/NDK. @nullable(heap=true)
tidak ada operasi di backend Java.
utf8InCpp
utf8InCpp
menyatakan bahwa sebuah String
direpresentasikan dalam format UTF8 untuk backend CPP. Seperti namanya, anotasi adalah larangan untuk backend lainnya. Secara khusus, String
selalu UTF16 di backend Java dan UTF8 di backend NDK.
Anotasi ini dapat dilampirkan di mana saja tipe String
dapat digunakan, termasuk nilai kembalian, parameter, deklarasi konstanta, dan bidang parsel.
Untuk backend CPP, @utf8InCpp String
di AIDL memetakan ke std::string
, sedangkan String
tanpa anotasi memetakan ke android::String16
tempat UTF16 digunakan.
Perhatikan 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 ditransmisikan. Ketika sebuah string diterima, string tersebut akan dikonversi dari UTF16 ke UTF8 jika dianotasi sebagai utf8InCpp
.
Stabilitas Vintf
VintfStability
menyatakan bahwa tipe yang ditentukan pengguna (antarmuka, parsel, dan enum) dapat digunakan di seluruh sistem dan domain vendor. Lihat AIDL untuk HAL untuk mengetahui lebih lanjut tentang interoperabilitas sistem-vendor.
Anotasi tidak mengubah tanda tangan tipe, tetapi ketika disetel, instans tipe ditandai sebagai stabil sehingga dapat berjalan melintasi vendor dan proses sistem.
Anotasi hanya dapat dilampirkan ke deklarasi tipe yang ditentukan pengguna seperti yang ditunjukkan di bawah ini:
@VintfStability
interface IFoo {
....
}
@VintfStability
parcelable Data {
....
}
@VintfStability
enum Type {
....
}
Ketika suatu tipe dianotasi dengan VintfStability
, tipe lain apa pun yang dirujuk dalam tipe tersebut juga harus dianotasi seperti itu. Pada contoh di bawah ini, 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 mendefinisikan tipe yang dianotasi dengan VintfStability
hanya dapat dibuat menggunakan tipe modul aidl_interface
Soong, dengan properti stability
disetel ke "vintf"
.
aidl_interface {
name: "my_interface",
srcs: [...],
stability: "vintf",
}
PenggunaanAplikasi yang Tidak Didukung
Anotasi UnsupportedAppUsage
menunjukkan bahwa jenis AIDL beranotasi adalah bagian dari antarmuka non-SDK yang telah dapat diakses untuk aplikasi lawas. Lihat Pembatasan pada antarmuka non-SDK untuk informasi selengkapnya tentang API tersembunyi.
Anotasi UnsupportedAppUsage
tidak memengaruhi perilaku kode yang dihasilkan. Anotasi hanya menganotasi kelas 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 larangan untuk backend non-Java.
Dukungan
Anotasi Backing
menentukan tipe penyimpanan tipe enum AIDL.
@Backing(type="int")
enum Color { RED, BLUE, }
Di backend CPP, di atas memancarkan kelas enum C++ bertipe int32_t
.
enum class Color : int32_t {
RED = 0,
BLUE = 1,
}
Jika anotasi dihilangkan, type
diasumsikan sebagai byte
, yang dipetakan ke int8_t
untuk backend CPP.
Argumen type
hanya dapat disetel ke tipe integral berikut:
-
byte
(lebar 8-bit) -
int
(lebar 32-bit) -
long
(lebar 64-bit)
JavaOnlyStableParcelable
JavaOnlyStableParcelable
menandai deklarasi parcelable (bukan definisi) sebagai stabil sehingga dapat direferensikan dari tipe AIDL stabil lainnya.
AIDL yang stabil mengharuskan semua tipe yang ditentukan pengguna stabil. Untuk parcelable, menjadi stabil mengharuskan bidangnya 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 itu tidak terstruktur (atau baru saja dideklarasikan), maka itu tidak dapat direferensikan.
parcelable Data; // Data is NOT a structured parcelable
parcelable AnotherData {
Data d; // Error
}
JavaOnlyStableParcelable
memungkinkan Anda untuk mengesampingkan pemeriksaan ketika parcelable yang Anda rujuk sudah tersedia dengan aman sebagai bagian dari Android SDK.
@JavaOnlyStableParcelable
parcelable Data;
parcelable AnotherData {
Data d; // OK
}
Turunan Jawa
JavaDerive
secara otomatis menghasilkan metode untuk tipe 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 tipe dan bidang. Misalnya:Data{number: 42, str: foo}
JavaDefault
JavaDefault
, ditambahkan di Android T (AOSP eksperimental), mengontrol apakah dukungan pembuatan versi implementasi default dibuat (untuk setDefaultImpl
). Dukungan ini tidak lagi dibuat secara default untuk menghemat ruang.
JawaPassthrough
JavaPassthrough
memungkinkan Java API yang dihasilkan dianotasi dengan anotasi Java arbitrer.
Anotasi berikut dalam 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 dipancarkan. Kompiler AIDL tidak melihat nilai parameter. Jika ada kesalahan sintaksis tingkat Java, itu tidak akan ditangkap oleh kompiler AIDL tetapi oleh kompiler Java.
Anotasi ini dapat dilampirkan ke entitas AIDL mana pun. Anotasi ini adalah larangan untuk backend non-Java.
Ukuran tetap
FixedSize
menandai paket terstruktur sebagai ukuran tetap. Setelah ditandai, parcelable tidak akan diizinkan untuk menambahkan bidang baru ke dalamnya. Semua bidang dari parcelable juga harus berupa tipe berukuran tetap, termasuk tipe primitif, enum, array ukuran tetap, dan parcelable lainnya yang ditandai dengan FixedSize
.
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 IHello {...}
Deskriptor antarmuka di atas adalah android.bar.IWorld
. Jika anotasi Descriptor
tidak ada, deskriptornya adalah android.foo.IHello
.
Ini berguna untuk mengganti nama antarmuka yang sudah diterbitkan. Membuat deskriptor antarmuka yang diganti namanya sama dengan deskriptor antarmuka sebelum penggantian nama memungkinkan kedua antarmuka untuk berbicara satu sama lain.
@sembunyikan di komentar
Kompiler AIDL mengenali @hide
dalam komentar dan meneruskannya ke output Java untuk metalava untuk diambil. Komentar ini memastikan bahwa sistem pembangunan Android mengetahui bahwa API AIDL bukan API SDK.
@ditinggalkan dalam komentar
Kompiler 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 entitas yang tidak digunakan lagi dengan anotasi/atribut khusus backend sehingga kode klien diperingatkan jika merujuk pada entitas yang tidak digunakan lagi. Misalnya, anotasi @Deprecated
dan tag @deprecated
dilampirkan ke kode yang dihasilkan Java.