AIDL از حاشیهنویسیهایی پشتیبانی میکند که به کامپایلر AIDL اطلاعات بیشتری در مورد عنصر حاشیهنویسی میدهد، که بر کد خرد تولید شده نیز تأثیر میگذارد.
سینتکس شبیه به جاوا است:
@AnnotationName(argument1=value, argument2=value) AidlEntity
در اینجا AnnotationName
نام حاشیهنویسی است و AidlEntity
یک موجودیت AIDL مانند interface Foo
، void method()
یا int arg
است. یک حاشیه نویسی به موجودی که آن را دنبال می کند پیوست می شود.
برخی از حاشیه نویسی ها می توانند آرگومان هایی را در داخل پرانتز قرار دهند، همانطور که در بالا نشان داده شده است. حاشیه نویسی هایی که استدلال ندارند نیازی به پرانتز ندارند. به عنوان مثال:
@AnnotationName AidlEntity
این حاشیه نویسی ها با حاشیه نویسی های جاوا یکسان نیستند، اگرچه بسیار شبیه به هم هستند. کاربران نمی توانند حاشیه نویسی سفارشی AIDL را تعریف کنند. حاشیه نویسی ها همه از پیش تعریف شده اند. برخی از حاشیه نویسی ها تنها بر یک باطن خاص تأثیر می گذارند و در سایر باطن ها بدون عملیات هستند. آنها محدودیت های مختلفی دارند که می توانند به آنها متصل شوند.
در اینجا لیستی از حاشیه نویسی های از پیش تعریف شده AIDL آمده است:
حاشیه نویسی ها | در نسخه اندروید اضافه شد |
---|---|
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
این حاشیه نویسی برای باطن جاوا بدون عملیات است. این به این دلیل است که در جاوا، همه انواع غیر ابتدایی با مرجع ارسال می شوند که می تواند null
باشد.
در پشتیبان CPP، @nullable T
به std::unique_ptr<T>
در اندروید 11 یا پایینتر و به std::optional<T>
در اندروید 12 یا بالاتر نگاشت میشود.
در باطن 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>>>
نگاشت std::unique_ptr<std::vector<std::unique_ptr<T>>>
در مورد CPP backend برای اندروید 11 یا پایین تر).
یک استثنا برای این نقشه برداری وجود دارد. هنگامی که T
IBinder
یا یک رابط AIDL است، @nullable
برای همه backendها به جز Rust غیر فعال است. In other words, both @nullable IBinder
and IBinder
equally map to android::sp<IBinder>
, which is already nullable because it is a strong pointer (CPP reads still enforce nullability, but the type is still android::sp<IBinder>
). در Rust، این نوعها فقط درصورتیکه با @nullable
حاشیهنویسی شوند، nullable
هستند. آنها در صورت حاشیه نویسی به Option<T>
نگاشت می شوند.
با شروع اندروید 13، @nullable(heap=true)
میتواند برای فیلدهای parcelable برای مدلسازی انواع بازگشتی استفاده شود. @nullable(heap=true)
نمی توان با پارامترهای متد یا انواع برگشتی استفاده کرد. هنگامی که با آن حاشیه نویسی می شود، این فیلد به یک مرجع تخصیص داده شده پشته ای std::unique_ptr<T>
در backendهای CPP/NDK نگاشت می شود. @nullable(heap=true)
در باطن جاوا بدون عملیات است.
utf8InCpp
utf8InCpp
اعلام می کند که یک String
در قالب UTF8 برای باطن CPP نشان داده شده است. همانطور که از نام آن مشخص است، حاشیه نویسی برای سایر باطن ها بدون عملیات است. به طور خاص، String
همیشه UTF16 در باطن جاوا و UTF8 در باطن NDK است.
این حاشیهنویسی را میتوان در هر جایی که بتوان از نوع String
استفاده کرد، از جمله مقادیر بازگشتی، پارامترها، اعلانهای ثابت و فیلدهای قابل بستهبندی پیوست کرد.
برای باطن CPP، @utf8InCpp String
در نقشه های AIDL به std::string
، در حالی که String
بدون حاشیه نویسی به android::String16
که در آن UTF16 استفاده می شود، نقشه می دهد.
توجه داشته باشید که وجود حاشیه نویسی utf8InCpp
نحوه انتقال رشته ها از طریق سیم را تغییر نمی دهد. رشته ها همیشه به صورت UTF16 از طریق سیم منتقل می شوند. یک رشته حاشیه نویسی utf8InCpp
قبل از انتقال به UTF16 تبدیل می شود. هنگامی که یک رشته دریافت می شود، اگر به عنوان utf8InCpp
حاشیه نویسی شده باشد، از UTF16 به UTF8 تبدیل می شود.
VintfStability
VintfStability
اعلام میکند که یک نوع تعریفشده توسط کاربر (رابط، بستهپذیر، و 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 است که برای برنامه های قدیمی در دسترس بوده است. برای اطلاعات بیشتر در مورد APIهای پنهان، به محدودیتهای رابطهای غیر SDK مراجعه کنید.
حاشیه نویسی UnsupportedAppUsage
بر رفتار کد تولید شده تأثیر نمی گذارد. حاشیه نویسی فقط کلاس جاوای تولید شده را با حاشیه نویسی جاوا به همین نام حاشیه نویسی می کند.
// in AIDL
@UnsupportedAppUsage
interface IFoo {...}
// in Java
@android.compat.annotation.UnsupportedAppUsage
public interface IFoo {...}
این یک برنامه بدون عملیات برای پشتیبان های غیر جاوا است.
پشتیبان گیری
حاشیه نویسی Backing
نوع ذخیره سازی یک نوع AIDL enum را مشخص می کند.
@Backing(type="int")
enum Color { RED, BLUE, }
در باطن CPP، یک کلاس C++ enum از نوع int32_t
منتشر میکند.
enum class Color : int32_t {
RED = 0,
BLUE = 1,
}
اگر حاشیهنویسی حذف شود، type
byte
در نظر گرفته میشود که برای backend CPP به int8_t
نگاشت میشود.
آرگومان type
را می توان فقط برای انواع انتگرال زیر تنظیم کرد:
-
byte
(عرض 8 بیت) -
int
(عرض 32 بیت) -
long
(64 بیت عرض)
NdkOnlyStableParcelable
NdkOnlyStableParcelable
یک اعلان parcelable (نه تعریف) را به عنوان پایدار علامت گذاری می کند تا بتوان آن را از سایر انواع AIDL پایدار ارجاع داد. این مانند JavaOnlyStableParcelable
است، اما NdkOnlyStableParcelable
یک اعلان بستهپذیر را بهجای جاوا برای باطن NDK بهعنوان پایدار علامتگذاری میکند.
برای استفاده از این بسته بندی:
- باید
ndk_header
مشخص کنید. - شما باید یک کتابخانه NDK داشته باشید که بسته پذیر را مشخص کند و کتابخانه باید در کتابخانه کامپایل شود. به عنوان مثال، در سیستم ساخت هسته در یک ماژول
cc_*
، ازstatic_libs
یاshared_libs
استفاده کنید. برایaidl_interface
، کتابخانه را در زیرadditional_shared_libraries
درAndroid.bp
اضافه کنید.
JavaOnlyStableParcelable
JavaOnlyStableParcelable
یک اعلان parcelable (نه تعریف) را به عنوان پایدار علامت گذاری می کند تا بتوان آن را از سایر انواع AIDL پایدار ارجاع داد.
AIDL پایدار مستلزم آن است که همه انواع تعریف شده توسط کاربر پایدار باشند. برای بستهبندیها، پایدار بودن مستلزم آن است که فیلدهای آن به صراحت در فایل منبع 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 Data; // Data is NOT a structured parcelable
parcelable AnotherData {
Data d; // Error
}
JavaOnlyStableParcelable
به شما امکان می دهد تا زمانی که بسته ای که به آن ارجاع می دهید به صورت ایمن به عنوان بخشی از Android SDK در دسترس است، بررسی را لغو کنید.
@JavaOnlyStableParcelable
parcelable Data;
parcelable AnotherData {
Data d; // OK
}
JavaDerive
JavaDerive
به طور خودکار متدهایی را برای انواع قابل تقسیم در باطن جاوا تولید می کند.
@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
اجازه می دهد تا API جاوا ایجاد شده با یک حاشیه نویسی دلخواه جاوا حاشیه نویسی شود.
حاشیه نویسی های زیر در 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 به مقدار پارامتر نگاه نمی کند. اگر هر گونه خطای نحوی در سطح جاوا وجود داشته باشد، توسط کامپایلر AIDL شناسایی نمی شود، بلکه توسط کامپایلر جاوا شناسایی می شود.
این حاشیه نویسی را می توان به هر موجودیت AIDL پیوست. این حاشیه نویسی برای برنامه های پشتیبان غیر جاوا یک برنامه بدون عملیات است.
FixedSize
FixedSize
یک بسته بندی ساختار یافته را به عنوان اندازه ثابت علامت گذاری می کند. پس از علامتگذاری، بستهبندی مجاز به افزودن فیلدهای جدید به آن نخواهد بود. همه فیلدهای parcelable نیز باید دارای انواع با اندازه ثابت باشند، از جمله انواع اولیه، enums، آرایههای با اندازه ثابت، و سایر قابلمههایی که با FixedSize
مشخص شدهاند.
این هیچ تضمینی برای بیت های مختلف ارائه نمی دهد و نباید برای ارتباط با بیت های مختلف به آن اعتماد کرد.
توصیفگر
Descriptor
به اجبار توصیفگر رابط یک رابط را مشخص می کند.
package android.foo;
@Descriptor(value="android.bar.IWorld")
interface IHello {...}
توصیف کننده این رابط android.bar.IWorld
است. اگر حاشیهنویسی Descriptor
وجود نداشته باشد، توصیفگر android.foo.IHello
.
این برای تغییر نام یک رابط از قبل منتشر شده مفید است. قبل از تغییر نام، توصیف کننده رابط تغییر نام یافته مشابه توصیف کننده رابط کاربری قبل از تغییر نام، به دو رابط اجازه می دهد تا با یکدیگر صحبت کنند.
@hide در نظرات
کامپایلر AIDL، @hide
در کامنتها تشخیص میدهد و آن را به خروجی جاوا ارسال میکند تا metalava به پیکاپ شود. این نظر تضمین می کند که سیستم ساخت اندروید می داند که APIهای AIDL APIهای SDK نیستند.
@ منسوخ شده در نظرات
کامپایلر AIDL، @deprecated
در نظرات به عنوان برچسبی برای شناسایی موجودیت AIDL که دیگر نباید استفاده شود، شناسایی می کند.
interface IFoo {
/** @deprecated use bar() instead */
void foo();
void bar();
}
هر پشتیبان موجودیت های منسوخ شده را با یک حاشیه نویسی یا ویژگی خاص باطن علامت گذاری می کند تا در صورت ارجاع به موجودیت های منسوخ شده به کد مشتری هشدار داده شود. به عنوان مثال، حاشیه نویسی @Deprecated
و تگ @deprecated
به کد تولید شده جاوا متصل می شوند.