AIDL از حاشیهنویسیهایی پشتیبانی میکند که اطلاعات بیشتری درباره عنصر حاشیهنویسیشده به کامپایلر AIDL میدهند، که این امر بر کد تهیسازه تولیدشده نیز تأثیر میگذارد.
نحو آن مشابه نحو Java است:
@AnnotationName(argument1=value, argument2=value) AidlEntity
در اینجا، AnnotationName نام گزارمان است و AidlEntity یک نهاد AIDL مانند interface Foo، void method()، یا int arg است. حاشیهنویسی به نهادی که پساز آن میآید پیوست میشود.
برخیاز گزارمانها میتوانند آرگومانهایی داشته باشند که درون پرانتز تنظیم شدهاند، همانطور که در مثال قبلی نشان داده شده است. گزارمانهایی که آرگومان ندارند نیازی به پرانتز ندارند. برای مثال:
@AnnotationName AidlEntity
این گزارمانها با گزارمانهای Java یکسان نیستند، اگرچه شبیه به هم هستند. همه حاشیهنویسیها ازپیش تعریف شدهاند، و محدودیتهایی برای جایی که میتوانید آنها را پیوست کنید وجود دارد. برخیاز گزارمانها فقط بر یک زیرینه خاص تأثیر میگذارند و در زیرینههای دیگر بدون عملکرد هستند.
در اینجا فهرست نشانگذاریهای ازپیشتعریفشده AIDL آمده است:
| حاشیهنویسیها | در نسخه 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 اعلام میکند که مقدار نهاد حاشیهنویسیشده میتواند تهی باشد.
این حاشیهنویسی را فقط میتوانید به انواع پاسخ روش، پارامترهای روش، و فیلدهای قابلبستهبندی پیوست کنید:
interface IFoo {
// method return types
@nullable Data method();
// method parameters
void method2(in @nullable Data d);
}
parcelable Data {
// parcelable fields
@nullable Data d;
}
نوشتارها نمیتوانند به انواع اولیه پیوست شوند. خطا بهشرح زیر است:
void method(in @nullable int a); // int is a primitive type
این گزارمان برای زیرینه Java بدون عملیات است. در جاوا، همه
انواع غیرابتدایی با ارجاع ارسال میشوند، که میتواند null باشد.
در زیرینه CPP، @nullable T در Android
11 یا پایینتر به std::unique_ptr<T> و در Android 12 یا بالاتر به std::optional<T> نگاشت میشود.
در زیرینه NDK، @nullable T به std::optional<T> نگاشت میشود.
در زیرینه Rust، @nullable T به Option<T> نگاشت میشود.
برای نوع فهرستمانند L مثل T[] یا List<T>، @nullable L به
std::optional<std::vector<std::optional<T>>> (یا
std::unique_ptr<std::vector<std::unique_ptr<T>>> درصورت استفاده از زیرینه CPP
برای Android 11 یا پایینتر) نگاشت میشود.
این نقشهبرداری استثنایی دارد. وقتی T، IBinder یا یک میانای AIDL باشد، @nullable برای پسزمینههای Java، CPP، و NDK یک عملیات بیتأثیر است. برای مثال، در زیرینه CPP، هم @nullable IBinder و هم IBinder بهطور یکسان به android::sp<IBinder> نگاشت میشوند، که ازقبل تهیپذیر است زیرا اشارهگر قوی است (CPP و NDK همچنان تهیپذیر بودن را اعمال میکنند، اما نوع android::sp<IBinder> یا ndk::SpAIBinder باقی میماند).
در زیرینه Rust، انواع که Default (IBinder، میاناهای AIDL، ParcelFileDescriptor، و بستههای بدون ساختار) را پیادهسازی نمیکنند، بسته به زمینهشان به
Option<T> نگاشت میشوند:
- انواع برگشتی روش،
inپارامتر، وinoutپارامتر: این انواع فقط درصورتی تهیپذیر هستند که با@nullableحاشیهنویسی شده باشند و بهOption<T>(یاOption<&T>برایinپارامتر و&mut Option<T>برایinoutپارامتر) نگاشت شوند. بدون@nullable، مستقیماً بهT(یا&Tو&mut T) نگاشت میشوند. - فیلدهای Parcelable و پارامترهای
out: ازآنجاییکه parcelableهای Rust تولیدشده ازDefaultمشتق میشوند و پارامترهایoutبا مقدار پیشفرض مقداردهی اولیه میشوند، این نوعها همیشه بهOption<T>نگاشت میشوند (و آرایههای اندازه ثابت در این زمینهها به[Option<T>; N]نگاشت میشوند، درحالیکه آرایههای پویا در پارامترهایoutبهVec<Option<T>>نگاشت میشوند)، حتی بدون@nullable. وقتی با@nullableحاشیهنویسی نشده باشد، غیرقابلتهی بودن همچنان در زمان اجرا درطول بستهبندی اعمال میشود (اگر مقدارNoneباشد،StatusCode::UNEXPECTED_NULLبرگردانده میشود).
از Android 13 به بعد، از @nullable(heap=true) میتوان برای
فیلدهای بستهشدنی برای مدلسازی انواع بازگشتی استفاده کرد. نمیتوان از @nullable(heap=true)
با پارامترهای روش یا انواع برگشتی استفاده کرد. وقتی با آن حاشیهنویسی میشود، فیلد به مرجع اختصاصیافته به توده std::unique_ptr<T> در پسزمینههای CPP و NDK نگاشت میشود. @nullable(heap=true) در زیرینه Java بدون عملیات است.
utf8InCpp
utf8InCpp اعلام میکند که String در قالب UTF8 برای
کارساز CPP نشان داده میشود. همانطور که از نام آن پیداست، این گزارمان برای دیگر زیرینهها یک عملیات بدون اثر است.
بهطور دقیق، String همیشه در پسای Java بهصورت UTF16 و در پسای NDK بهصورت UTF8 است.
این گزارمان میتواند در هر جایی که نوع String میتواند استفاده شود پیوست شود،
ازجمله مقادیر برگشتی، پارامترها، بیانیههای ثابت، و فیلدهای بستهشدنی.
برای زیرینه CPP، @utf8InCpp String در AIDL به std::string نگاشت میشود، درحالیکه
String بدون گزارمان به android::String16 نگاشت میشود که در آن از UTF16 استفاده میشود.
VintfStability
VintfStability اعلام میکند که نوع تعریفشده توسط کاربر (میانای، parcelable،
و enum) میتواند در سراسر دامنههای سیستم و فروشنده استفاده شود. برای اطلاعات بیشتر درباره
قابلیت همکنشپذیری سیستم-فروشنده،
AIDL برای HAL را ببینید.
حاشیهنویسی امضای نوع را تغییر نمیدهد، اما وقتی تنظیم میشود، نمونه نوع بهعنوان پایدار علامتگذاری میشود تا بتواند در سراسر فروشنده و فرایندهای سیستم حرکت کند.
حاشیهنویسی را فقط میتوان به اعلانهای نوع تعریفشده توسط کاربر پیوست کرد، همانطور که در اینجا نشان داده شده است:
@VintfStability
interface IFoo {
....
}
@VintfStability
parcelable Data {
....
}
@VintfStability
enum Type {
....
}
وقتی نوعی با VintfStability حاشیهنویسی میشود، هر نوع دیگری که در آن نوع به آن ارجاع داده میشود نیز باید به همین صورت حاشیهنویسی شود. در مثال زیر، Data و IBar باید هر دو با 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 {...}
علاوهبراین، فایلهای AIDL که انواع حاشیهنویسیشده با VintfStability را تعریف میکنند
فقط بااستفاده از نوع ماژول aidl_interface Soong قابلساخت هستند،
درحالیکه ویژگی stability روی vintf تنظیم شده است:
aidl_interface {
name: "my_interface",
srcs: [...],
stability: "vintf",
}
UnsupportedAppUsage
گزارمان UnsupportedAppUsage نشان میدهد که نوع AIDL گزارمانگذاریشده بخشی از میانای غیر SDK است که برای برنامههای قدیمی دردسترس بوده است.
برای کسب اطلاعات بیشتر درباره میاناهای برنامهسازی کاربردی پنهان، محدودیتهای مربوط به میاناهای غیر SDK
را ببینید.
حاشیهنویسی UnsupportedAppUsage بر رفتار کد تولیدشده تأثیری ندارد. حاشیهنویسی فقط کلاس Java تولیدشده را با حاشیهنویسی Java با همان نام حاشیهنویسی میکند:
// in AIDL
@UnsupportedAppUsage
interface IFoo {...}
// in Java
@android.compat.annotation.UnsupportedAppUsage
public interface IFoo {...}
این یک عملیات بدون اثر برای زمینههای غیرجاوا است.
حاشیهنویسی پشتیبان
حاشیهنویسی Backing نوع ذخیرهسازی نوع شمارشی AIDL را مشخص میکند:
@Backing(type="int")
enum Color { RED, BLUE, }
در پسای CPP، این یک کلاس شمارشی C++ از نوع int32_t منتشر میکند:
enum class Color : int32_t {
RED = 0,
BLUE = 1,
}
اگر حاشیهنویسی حذف شود، فرض میشود type byte است که به int8_t برای باطن CPP نگاشت میشود.
آرگومان type را فقط میتوان برای انواع انتگرال زیر تنظیم کرد:
-
byte(۸ بیت پهنا) -
int(عرض ۳۲ بیت) -
long(عرض ۶۴ بیت)
NdkOnlyStableParcelable
NdkOnlyStableParcelable اعلامیه بستهشدنی (نه تعریف) را بهعنوان پایدار علامتگذاری میکند
تا بتواند از انواع AIDL پایدار دیگر ارجاع داده شود. این
شبیه JavaOnlyStableParcelable است، اما
NdkOnlyStableParcelable اعلامیه دستهبندی را بهجای جاوا برای
پشتیبان NDK بهعنوان پایدار علامتگذاری میکند.
برای استفاده از این parcelable:
- باید
ndk_headerرا مشخص کنید. - باید کتابخانه NDK داشته باشید که parcelable را مشخص کند و کتابخانه باید در کتابخانه
کامپایل شود. برای مثال، در سیستم ساختار اصلی در واحد
cc_*، ازstatic_libsیاshared_libsاستفاده کنید. برایaidl_interface، کتابخانه را درadditional_shared_librariesدرAndroid.bpاضافه کنید.
JavaOnlyStableParcelable
JavaOnlyStableParcelable اعلامیه بستهشدنی (نه تعریف) را بهعنوان پایدار علامتگذاری میکند
تا بتواند از انواع AIDL پایدار دیگر ارجاع داده شود.
AIDL پایدار مستلزم آن است که همه انواع تعریفشده توسط کاربر پایدار باشند. برای parcelable، پایدار بودن مستلزم این است که فیلدهای آن بهطور صریح در فایل منبع 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
}
اگر parcelable بدون ساختار باشد (یا فقط اعلام شده باشد)، نمیتوان به آن ارجاع داد:
parcelable Data; // Data is NOT a structured parcelable
parcelable AnotherData {
Data d; // Error
}
JavaOnlyStableParcelable به شما امکان میدهد وقتی parcelable
مورد ارجاع شما بهعنوان بخشی از کیت توسعه نرمافزار Android بهطور ایمن دردسترس است، بررسی را لغو کنید:
@JavaOnlyStableParcelable
parcelable Data;
parcelable AnotherData {
Data d; // OK
}
JavaDerive
JavaDerive بهطور خودکار روشهایی برای انواع بستهشدنی در
پشتیبان Java تولید میکند:
@JavaDerive(equals = true, toString = true)
parcelable Data {
int number;
String str;
}
این گزارمان برای کنترل آنچه باید تولید شود به پارامترهای اضافی نیاز دارد. پارامترهای پشتیبانیشده عبارتاند از:
-
equals=trueروشهایequalsوhashCodeرا تولید میکند. -
toString=trueروشtoStringرا تولید میکند که نام نوع و فیلدها را چاپ میکند، برای مثال،Data{number: 42, str: foo}.
JavaDefault (منسوخشده)
JavaDefault، که در Android 13 اضافه شده است، کنترل میکند که آیا پشتیبانی نسخهبندی پیادهسازی پیشفرض تولید میشود یا نه (برای setDefaultImpl). این پشتیبانی دیگر بهطور پیشفرض تولید نمیشود تا در فضا صرفهجویی شود.
JavaPassthrough
JavaPassthrough اجازه میدهد میانای برنامهسازی کاربردی Java تولیدشده با حاشیهنویسی دلخواه Java حاشیهنویسی شود.
این حاشیهنویسیها در AIDL:
@JavaPassthrough(annotation="@android.annotation.Alice")
@JavaPassthrough(annotation="@com.android.Alice(arg=com.android.Alice.Value.A)")
در کد جاوا تولیدشده به این تبدیل میشود:
@android.annotation.Alice
@com.android.Alice(arg=com.android.Alice.Value.A)
مقدار پارامتر annotation مستقیماً منتشر میشود. گردآورنده AIDL مقدار پارامتر را بررسی نمیکند. اگر هرگونه
خطای نحوی در سطح Java وجود داشته باشد، توسط کامپایلر AIDL شناسایی نخواهد شد، بلکه توسط
کامپایلر Java شناسایی میشود.
این حاشیهنویسی را میتوان به هر موجودیت AIDL پیوست کرد. این گزارمان برای زیرینههای غیرجاوا یک عملیات بدون اثر است.
RustDerive
RustDerive بهطور خودکار ویژگیها را برای انواع Rust تولیدشده پیادهسازی میکند.
این گزارمان برای کنترل آنچه باید تولید شود به پارامترهای اضافی نیاز دارد. پارامترهای پشتیبانیشده عبارتاند از:
Copy=trueClone=trueOrd=truePartialOrd=trueEq=truePartialEq=trueHash=true
برای توضیحات این ویژگیها، به مستندات Rust مراجعه کنید.
اندازه ثابت
FixedSize یک parcelable ساختاریافته را بهعنوان اندازه ثابت علامتگذاری میکند. پساز علامتگذاری، نمیتوانید فیلدهای جدیدی به parcelable اضافه کنید. همه فیلدهای
parcelable باید از نوع اندازه ثابت باشند، ازجمله انواع اولیه،
تعداد، آرایههای اندازه ثابت، و parcelableهای دیگری که با FixedSize علامتگذاری شدهاند.
FixedSize شیء دارای اندازه و تراز پایدار در پسای ndk هستند.
| نوع | اندازه (بایت) | تراز (بایت) |
|---|---|---|
boolean |
1 |
1 |
byte |
1 |
1 |
char |
2 |
2 |
int |
4 |
4 |
long |
8 |
8 |
float |
4 |
4 |
double |
8 |
8 |
parcelable |
اندازه کل همه فیلدها | بزرگترین تراز همه فیلدها |
union |
بزرگترین اندازه همه فیلدها | بزرگترین تراز همه فیلدها |
enum |
اندازه نوع پشتیبان | تراز کردن نوع پشتیبان |
T[N] (آرایه با اندازه ثابت) |
اندازه T * N |
تراز T |
String, IBinder, FileDescriptor, ParcelFileDescriptor |
N/A |
N/A |
توصیفگر
Descriptor بهطور اجباری مشخصکننده میانای یک میانای کاربری را مشخص میکند:
package android.foo;
@Descriptor(value="android.bar.IWorld")
interface IHello {...}
توصیفگر این میانای کاربری android.bar.IWorld است. اگر گزارمان
Descriptor وجود نداشته باشد، توصیفگر
android.foo.IHello خواهد بود.
این گزینه برای تغییر نام واسطی که قبلاً منتشر شده است مفید است. اگر توصیفگر میانای تغییرنامیافته را با توصیفگر میانای قبلاز تغییرنام یکسان کنید، این دو میانا میتوانند با یکدیگر ارتباط برقرار کنند.
@hide در نظرات
گردآورنده AIDL @hide را در نظرات تشخیص میدهد و آن را به
برونداد جاوا برای metalava ارسال میکند تا آن را دریافت کند. این نظر کمک میکند تا مطمئن شوید که
سیستم ساخت Android تشخیص میدهد که میاناهای برنامهسازی کاربردی AIDL میاناهای برنامهسازی کاربردی کیت توسعه نرمافزار نیستند.
deprecated@ در نظرات
گردآورنده AIDL @deprecated را در نظرات بهعنوان برچسبی برای شناسایی نهاد AIDL که دیگر نباید استفاده شود تشخیص میدهد:
interface IFoo {
/** @deprecated use bar() instead */
void foo();
void bar();
}
هر زیرینه نهادهای منسوخشده را با یک شرح یا
مشخصه مختص زیرینه علامتگذاری میکند تا اگر کد کارخواه به نهادهای منسوخشده
ارجاع دهد، به آن هشدار داده شود. برای مثال، @Deprecated گزارمان و @deprecated
برچسب به کد تولیدشده Java پیوست شده است.