AIDL mendukung anotasi yang memberikan info tambahan kepada kompiler AIDL tentang elemen yang dianotasi, yang juga memengaruhi kode rintisan yang dihasilkan.
Sintaksnya 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 mungkin memiliki argumen yang diatur di dalam tanda kurung, seperti yang ditunjukkan di atas. Anotasi yang tidak memiliki argumen tidak memerlukan tanda kurung. Misalnya:
@AnnotationName AidlEntity
Anotasi ini tidak sama dengan anotasi Java, meski terlihat sangat mirip. Pengguna tidak dapat menentukan anotasi AIDL khusus; semua anotasi sudah ditentukan sebelumnya. Beberapa anotasi hanya memengaruhi backend tertentu dan tidak dapat digunakan di backend lainnya. Mereka memiliki batasan 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 |
NdkOnlyStableParcelable | 14 |
JavaOnlyStableParcelable | 11 |
JavaDerive | 12 |
JavaPassthrough | 12 |
FixedSize | 12 |
Descriptor | 12 |
dapat dibatalkan
nullable
menyatakan bahwa nilai entitas yang dianotasi 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 dapat digunakan untuk backend Java. Hal ini karena, di Java, semua tipe non-primitif diteruskan dengan referensi, yang bisa berupa null
.
Di backend CPP, @nullable T
dipetakan 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 dipetakan ke std::optional<T>
.
Untuk tipe 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>>>
dalam kasus backend CPP untuk Android 11 atau lebih rendah).
Ada pengecualian untuk pemetaan ini. Jika T
adalah IBinder
atau antarmuka AIDL, @nullable
tidak boleh dijalankan. Dengan kata lain, @nullable IBinder
dan IBinder
sama-sama dipetakan ke android::sp<IBinder>
, yang sudah dapat dibatalkan karena merupakan penunjuk yang kuat (pembacaan CPP masih menerapkan nullabilitas, tetapi tipenya tetap android::sp<IBinder>
).
Dimulai dengan Android 13, @nullable(heap=true)
dapat digunakan untuk kolom yang dapat dibagi untuk memodelkan tipe rekursif. @nullable(heap=true)
tidak dapat digunakan dengan parameter metode atau tipe kembalian. Saat dianotasi dengannya, bidang tersebut 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
mendeklarasikan bahwa sebuah String
direpresentasikan dalam format UTF8 untuk backend CPP. Seperti yang ditunjukkan oleh namanya, anotasi ini tidak berlaku untuk backend lainnya. Secara khusus, String
selalu berupa UTF16 di backend Java dan UTF8 di backend NDK.
Anotasi ini dapat dilampirkan di mana pun tipe String
dapat digunakan, termasuk nilai kembalian, parameter, deklarasi konstan, dan bidang yang dapat dibagi.
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 transmisi string melalui kabel. String selalu ditransmisikan sebagai UTF16 melalui kabel. String beranotasi utf8InCpp
dikonversi ke UTF16 sebelum dikirim. Ketika sebuah string diterima, string tersebut 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 dari tipe tersebut, namun ketika diatur, instance dari tipe tersebut 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 direferensikan dalam tipe tersebut juga harus dianotasi seperti itu. Pada contoh di bawah, 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, tipe definisi file AIDL yang dianotasi dengan VintfStability
hanya dapat dibuat menggunakan tipe modul aidl_interface
Soong, dengan properti stability
diatur ke "vintf"
.
aidl_interface {
name: "my_interface",
srcs: [...],
stability: "vintf",
}
Penggunaan Aplikasi Tidak Didukung
Anotasi UnsupportedAppUsage
menunjukkan bahwa jenis AIDL yang dianotasi adalah bagian dari antarmuka non-SDK yang dapat diakses untuk aplikasi lama. Lihat Pembatasan antarmuka non-SDK untuk informasi selengkapnya tentang API tersembunyi.
Anotasi UnsupportedAppUsage
tidak memengaruhi perilaku kode yang dihasilkan. Anotasi hanya memberi anotasi pada 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-Jawa.
Dukungan
Anotasi Backing
menentukan tipe penyimpanan tipe enum AIDL.
@Backing(type="int")
enum Color { RED, BLUE, }
Di backend CPP, di atas memancarkan kelas C++ enum bertipe int32_t
.
enum class Color : int32_t {
RED = 0,
BLUE = 1,
}
Jika anotasi dihilangkan, type
diasumsikan byte
, yang dipetakan ke int8_t
untuk backend CPP.
Argumen type
hanya dapat diatur ke tipe integral berikut:
-
byte
(lebar 8-bit) -
int
(lebar 32-bit) -
long
(lebar 64-bit)
NdkOnlyStableParcelable
NdkOnlyStableParcelable
menandai deklarasi yang dapat dibagi (bukan definisi) sebagai stabil sehingga dapat direferensikan dari tipe AIDL stabil lainnya. Ini seperti JavaOnlyStableParcelable
, namun NdkOnlyStableParcelable
menandai deklarasi parsel sebagai stabil untuk backend NDK, bukan untuk Java.
Untuk menggunakan paket ini: * Anda harus menentukan ndk_header
. * Anda harus memiliki perpustakaan NDK yang menentukan paketnya dan perpustakaan tersebut harus dikompilasi ke dalam perpustakaan. Misalnya, dalam sistem pembangunan inti pada modul cc_*
, gunakan static_libs
atau shared_libs
. Untuk aidl_interface
, tambahkan perpustakaan di bawah additional_shared_libraries
di Android.bp
.
JavaOnlyStableParcelable
JavaOnlyStableParcelable
menandai deklarasi yang dapat dibagi (bukan definisi) sebagai stabil sehingga dapat direferensikan dari tipe AIDL stabil lainnya.
AIDL yang stabil mengharuskan semua tipe yang ditentukan pengguna stabil. Untuk parsel, 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 parsel tidak terstruktur (atau baru saja dideklarasikan), maka parsel tersebut tidak dapat direferensikan.
parcelable Data; // Data is NOT a structured parcelable
parcelable AnotherData {
Data d; // Error
}
JavaOnlyStableParcelable
memungkinkan Anda mengganti pemeriksaan ketika paket yang Anda rujuk sudah tersedia dengan aman sebagai bagian dari Android SDK.
@JavaOnlyStableParcelable
parcelable Data;
parcelable AnotherData {
Data d; // OK
}
JavaDeriv
JavaDerive
secara otomatis menghasilkan metode untuk tipe paket 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
dengan danhashCode
. -
toString=true
menghasilkan metodetoString
yang mencetak nama jenis dan bidang. Misalnya:Data{number: 42, str: foo}
JavaDefault
JavaDefault
, yang ditambahkan di Android 13, mengontrol apakah dukungan pembuatan versi implementasi default dihasilkan (untuk setDefaultImpl
). Dukungan ini tidak lagi dibuat secara default untuk menghemat ruang.
JavaPassthrough
JavaPassthrough
memungkinkan Java API yang dihasilkan dianotasi dengan anotasi Java yang berubah-ubah.
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 dipancarkan. Kompiler AIDL tidak melihat nilai parameter. Jika ada kesalahan sintaksis tingkat Java, kesalahan tersebut tidak akan ditangkap oleh kompiler AIDL tetapi oleh kompiler Java.
Anotasi ini dapat dilampirkan ke entitas AIDL mana pun. Anotasi ini tidak berlaku untuk backend non-Jawa.
Ukuran tetap
FixedSize
menandai parsel terstruktur sebagai ukuran tetap. Setelah ditandai, parsel tidak akan diizinkan untuk menambahkan bidang baru ke dalamnya. Semua bidang dari parsel juga harus bertipe berukuran tetap, termasuk tipe primitif, enum, array berukuran tetap, dan parsel lainnya yang ditandai dengan FixedSize
.
Hal ini tidak memberikan jaminan apa pun pada bitness yang berbeda dan tidak dapat diandalkan untuk komunikasi bitness campuran.
Deskripsi
Descriptor
secara paksa menentukan deskriptor antarmuka 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 dipublikasikan. Menjadikan deskriptor antarmuka yang diubah 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 keluaran Java untuk diambil oleh metalava. Komentar ini memastikan bahwa sistem build Android mengetahui bahwa API AIDL bukanlah API SDK.
@tidak digunakan lagi 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.