באמצעות AIDL יש תמיכה בהערות שמספקות מידע נוסף למהדר AIDL על הרכיב עם ההערה. הפעולה הזו משפיעה גם על קוד ה-stub שנוצר.
התחביר דומה לתחביר של Java:
@AnnotationName(argument1=value, argument2=value) AidlEntity
כאן, AnnotationName
הוא שם ההערה, ו-AidlEntity
הוא ישות AIDL כמו interface Foo
, void method()
או int arg
. הערה מצורפת לישות שעוקבת אחריה.
עבור חלק מההערות אפשר להגדיר ארגומנטים בתוך הסוגריים, כפי שמוצג למעלה. בהערות שאין בהן ארגומנט אין צורך בסוגריים. לדוגמה:
@AnnotationName AidlEntity
ההערות האלו לא זהות להערות ב-Java, למרות שהן נראות דומות מאוד. המשתמשים לא יכולים להגדיר הערות מותאמות אישית ב-AIDL. כולן מוגדרות מראש. חלק מההערות משפיעות רק על קצה עורפי מסוים והן לא פועלות בקצוות עורפיים אחרים. יש להם הגבלות שונות שאליהן אפשר לצרף אותם.
רשימה של הערות 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 |
ערך null
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. הסיבה לכך היא שב-Java, כל הסוגים שאינם פרימיטיביים מועברים באמצעות הפניה, שיכולה להיות null
.
בקצה העורפי של CPP, @nullable T
ממופה אל std::unique_ptr<T>
ב-Android 11 ומטה, ול-std::optional<T>
ב-Android 12 ואילך.
בקצה העורפי של NDK, @nullable T
תמיד ממופה ל-std::optional<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
הוא ללא תפעול. במילים אחרות, גם @nullable IBinder
וגם IBinder
ממופים באופן שווה ל-android::sp<IBinder>
, וזהו כבר ערך null כי הוא מצביע חזק (CPP קורא עדיין אפשרות null, אבל הסוג עדיין android::sp<IBinder>
).
החל מ-Android 13, אפשר להשתמש ב-@nullable(heap=true)
לשדות שניתן לשתף כדי ליצור מודלים רקורסיביים. אי אפשר להשתמש ב-@nullable(heap=true)
עם פרמטרים של שיטות או סוגי החזרה. כשמוסיפים לו הערות, השדה ממופה לקובץ עזר של std::unique_ptr<T>
שהוקצה בשביל הזיכרון, בקצוות העורפיים של CPP/NDK. השירות @nullable(heap=true)
לא פעיל בקצה העורפי של Java.
utf8InCpp
utf8InCpp
מצהיר ש-String
מיוצג בפורמט UTF8 עבור הקצה העורפי של CPP. כפי שמציין ששמו מציין, ההערה מבוטלת בקצוות עורפיים אחרים.
באופן ספציפי, הערך של String
הוא תמיד UTF16 בקצה העורפי של Java ו-UTF8 בקצה העורפי NDK.
אפשר לצרף את ההערה הזו בכל מקום שבו אפשר להשתמש בסוג String
, כולל ערכי החזרה, פרמטרים, הצהרות קבועות ושדות שניתנים להפרדה.
בקצה העורפי של CPP, @utf8InCpp String
ב-AIDL ממופה אל std::string
, ואילו
String
בלי ההערות ממופה ל-android::String16
שבו נעשה שימוש ב-UTF16.
שימו לב שעצם קיומו של ההערה utf8InCpp
לא משנה את האופן שבו מחרוזות מועברות על החוט. המחרוזות תמיד נשלחות כ-UTF16 דרך החוט. מחרוזת עם הערות utf8InCpp
מומרת ל-UTF16 לפני ההעברה. כשמתקבלת מחרוזת, היא מומרת מ-UTF16 ל-UTF8 אם מוסיפים לה הערות כ-utf8InCpp
.
יציבות וינטג'
VintfStability
מצהיר/ה שאפשר להשתמש בסוג שהוגדר על ידי המשתמש (ממשק, parcelable ו-enum) בכל הדומיינים של המערכת ושל הספקים. מידע נוסף על יכולת פעולה הדדית של ספק מערכת זמין במאמר AIDL ל-HALs.
ההערה לא משנה את החתימה של הסוג, אבל כשהיא מוגדרת, המכונה מהסוג הזה מסומנת כיציבה כדי לאפשר מעבר בתהליכי הספק והמערכת.
אפשר לצרף את ההערה רק להצהרות מסוג מוגדר על ידי המשתמש, כפי שמוצג כאן:
@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
Sung, כשהמאפיין stability
מוגדר ל-"vintf"
.
aidl_interface {
name: "my_interface",
srcs: [...],
stability: "vintf",
}
שימוש באפליקציה לא נתמך
ההערה UnsupportedAppUsage
מציינת שסוג AIDL עם הערות הוא חלק מהממשק שאינו SDK שניתן לגשת אליו באפליקציות מדור קודם.
למידע נוסף על ממשקי ה-API המוסתרים, ראו הגבלות על ממשקים שאינם SDK.
ההערה UnsupportedAppUsage
לא משפיעה על ההתנהגות של הקוד שנוצר. בהערה מוסיפים הערות רק למחלקה של Java שנוצרה עם ההערה של Java עם אותו השם.
// in AIDL
@UnsupportedAppUsage
interface IFoo {...}
// in Java
@android.compat.annotation.UnsupportedAppUsage
public interface IFoo {...}
זוהי פעולה ללא פעולה לקצוות עורפיים שאינם של Java.
גיבוי
ההערה Backing
מציינת את סוג האחסון של סוג 'טיפוסים בני מנייה (enum)' מסוג 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
(ברוחב 8 ביט)int
(ברוחב 32 ביט)long
(רוחב 64 ביט)
NdkOnlyStableParcelable
NdkOnlyStableParcelable
מסמן הצהרה מסוג parcelable (לא הגדרה) כיציבה, כך שאפשר להפנות אליה מסוגי AIDL יציבים אחרים. זה דומה ל-JavaOnlyStableParcelable
, אבל NdkOnlyStableParcelable
מסמן הצהרה מסוג Package כיציבה לקצה העורפי NDK במקום ל-Java.
כדי להשתמש בחבילה הזו:
- צריך לציין
ndk_header
. - צריכה להיות לכם ספריית NDK שמציינת את החבילה, וצריך להדר אותה בספרייה. לדוגמה, במערכת build בסיסית של מודול
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
יוצר באופן אוטומטי methods לסוגים של מגרשים בקצה העורפי של Java.
@JavaDerive(equals = true, toString = true)
parcelable Data {
int number;
String str;
}
ההערה דורשת פרמטרים נוספים כדי לקבוע מה ליצור. הפרמטרים הנתמכים הם:
- הפונקציה
equals=true
יוצרת methodequals
ו-hashCode
. toString=true
יוצרת method ל-toString
שמדפיסה את שם הסוג והשדות. לדוגמה:Data{number: 42, str: foo}
ברירת מחדל של Java
JavaDefault
, שנוסף ב-Android 13, קובע אם תיווצר תמיכה ברירת מחדל לניהול גרסאות של הטמעה (ל-setDefaultImpl
). התמיכה הזו לא נוצרת יותר כברירת מחדל כדי לחסוך מקום.
JavaPassthrough
JavaPassthrough
מאפשר להוסיף הערות ל-API של 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)
בקוד ה-Java שנוצר.
הערך של הפרמטר annotation
נפלט ישירות. המהדר של AIDL לא בודק את הערך של הפרמטר. אם יש שגיאת תחביר ברמת Java, היא לא תזוהה על ידי מהדר AIDL אלא על ידי מהדר (compiler) Java.
אפשר לצרף את ההערה הזו לכל ישות AIDL. האנוטציה הזו היא ללא תפעול לקצוות עורפיים שאינם של Java.
גודל קבוע
המאפיין FixedSize
מסמן חבילה מובנית כגודל קבוע. אחרי שמסמנים את החבילה, לא תהיה אפשרות להוסיף אליה שדות חדשים. גם כל השדות של המגרש צריכים להיות בגודל קבוע, כולל סוגים פרימיטיביים, טיפוסים בני מנייה (enums), מערכים בגודל קבוע ומגרשים אחרים שמסומנים ב-FixedSize
.
הפעולה הזו לא מספקת אחריות לגבי ביטים שונים, ואין להסתמך עליה לתקשורת עם ביטים מעורבים.
מתאר
Descriptor
מציין בכוח את מתאר הממשק של הממשק.
package android.foo;
@Descriptor(value="android.bar.IWorld")
interface IHello {...}
התיאור של הממשק הזה הוא android.bar.IWorld
. אם ההערה
Descriptor
חסרה, המתאר יהיה android.foo.IHello
.
האפשרות הזו שימושית כשמשנים שם של ממשק שכבר פורסם. יצירת התיאור של הממשק עם השם החדש זהה לתיאור הממשק לפני שינוי השם מאפשרת לשני הממשקים לדבר זה עם זה.
@הסתרה בתגובות
המהדר של AIDL מזהה את @hide
בתגובות ומעביר אותו לפלט של Java כדי ש- Metalava יגיע לאיסוף. ההערה הזו מבטיחה שמערכת ה-build של Android תדע שממשקי API של AIDL הם לא ממשקי API של SDK.
@הוצא משימוש בתגובות
המהדר של AIDL מזהה את @deprecated
בתגובות כתג, כדי לזהות ישות AIDL שלא צריכה יותר להשתמש בה.
interface IFoo {
/** @deprecated use bar() instead */
void foo();
void bar();
}
כל קצה עורפי מסמן ישויות שהוצאו משימוש עם הערה או מאפיין ספציפיים לקצה העורפי, כדי שקוד הלקוח יקבל אזהרה אם הוא מפנה לישויות שהוצאו משימוש. לדוגמה, ההערה @Deprecated
והתג @deprecated
מצורפים לקוד שנוצר ב-Java.