הערות ב-AIDL

AIDL תומך בהערות המעניקות למהדר AIDL מידע נוסף על האלמנט המוער, אשר משפיע גם על קוד הסטאב שנוצר.

התחביר דומה לזה של Java:

@AnnotationName(argument1=value, argument2=value) AidlEntity

כאן, AnnotationName הוא השם של ההערה, ו- AidlEntity היא ישות AIDL כמו interface Foo , void method() או int arg . ביאור מצורף לישות שאחריה.

לחלק מהביאורים יכולים להיות ארגומנטים מוגדרים בתוך הסוגריים, כפי שמוצג לעיל. הערות שאין בהן טיעון אינן זקוקות לסוגריים. לדוגמה:

@AnnotationName AidlEntity

הערות אלו אינן זהות להערות Java, למרות שהן נראות דומות מאוד. משתמשים לא יכולים להגדיר הערות AIDL מותאמות אישית; ההערות כולן מוגדרות מראש. הערות מסוימות משפיעות רק על קצה עורפי מסוים ואינן פועלות בקצה עורפי אחרים. יש להם הגבלות שונות שבהן ניתן לצרף אותם.

להלן רשימה של הערות AIDL שהוגדרו מראש:

הערות נוסף בגרסת אנדרואיד
nullable 7
utf8InCpp 7
VintfStability 11
UnsupportedAppUsage 10
Hide 11
Backing 11
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 backend, @nullable T ממפה ל- std::unique_ptr<T> באנדרואיד 11 ומטה, ול- std::optional<T> באנדרואיד 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 backend עבור אנדרואיד 11 ומטה).

יש חריג למיפוי זה. כאשר T הוא IBinder או ממשק AIDL, @nullable אינו פועל. במילים אחרות, הן @nullable IBinder והן IBinder באותה מידה android::sp<IBinder> , שכבר ניתן ל-null כי הוא מצביע חזק (קריאת CPP עדיין אוכפת את nullability, אבל הסוג הוא עדיין android::sp<IBinder> ).

החל מ-Android T (ניסיוני AOSP), ניתן להשתמש ב-@ @nullable(heap=true) עבור שדות הניתנים לחלוקה למודל של סוגים רקורסיביים. לא ניתן להשתמש ב- @nullable(heap=true) עם פרמטרי שיטה או סוגי החזרה. כאשר מציינים בו הערות, השדה ממופה להפניה שהוקצתה בערימה std::unique_ptr<T> של CPP/NDK. @nullable(heap=true) אינו פועל ב-Java backend.

utf8InCpp

utf8InCpp מצהיר String מיוצגת בפורמט UTF8 עבור ה-CPP backend. כפי שהשם שלה מעיד, ההערה היא ללא הפעלה עבור חלקים עורפיים אחרים. באופן ספציפי, String היא תמיד UTF16 ב-Java backend ו-UTF8 ב-NDK backend.

ניתן לצרף הערה זו בכל מקום שבו ניתן להשתמש בסוג String , כולל ערכי החזרה, פרמטרים, הצהרות קבועות ושדות הניתנים לחלוקה.

עבור הקצה העורפי של CPP, @utf8InCpp String ב-AIDL מפות ל- std::string , ואילו String ללא ההערות ממפה android::String16 שבה נעשה שימוש ב-UTF16.

שים לב שקיומה של ההערה utf8InCpp לא משנה את האופן שבו מחרוזות מועברות דרך החוט. מיתרים מועברים תמיד כ-UTF16 על החוט. מחרוזת עם הערות utf8InCpp מומרת ל-UTF16 לפני שהיא משודרת. כאשר מחרוזת מתקבלת, היא מומרת מ-UTF16 ל-UTF8 אם היא סומנה כ- utf8InCpp .

VintfStability

VintfStability מצהירה שניתן להשתמש בסוג מוגדר על ידי משתמש (ממשק, ניתן לחלוקה ו-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 , כאשר מאפיין stability מוגדר ל- "vintf" .

aidl_interface {
    name: "my_interface",
    srcs: [...],
    stability: "vintf",
}

UnsupportedAppUsage

ההערה UnsupportedAppUsage מציינת שסוג ה-AIDL המוער הוא חלק מהממשק שאינו SDK שהיה נגיש עבור אפליקציות מדור קודם. ראה הגבלות על ממשקים שאינם SDK למידע נוסף על ממשקי ה-API הנסתרים.

ההערה UnsupportedAppUsage אינה משפיעה על התנהגות הקוד שנוצר. ההערה מביאה רק הערה למחלקת Java שנוצרה עם הערת Java באותו שם.

// in AIDL
@UnsupportedAppUsage
interface IFoo {...}

// in Java
@android.compat.annotation.UnsupportedAppUsage
public interface IFoo {...}

זוהי פעולה ללא הפעלה עבור קצה גבה שאינם Java.

גיבוי

הערת Backing מציינת את סוג האחסון של סוג AIDL enum.

@Backing(type="int")
enum Color { RED, BLUE, }

ב-CPP backend, האמור לעיל פולט מחלקה C++ enum מסוג int32_t .

enum class Color : int32_t {
    RED = 0,
    BLUE = 1,
}

אם ההערה מושמטת, ההנחה היא type הוא byte , שממפה ל- int8_t עבור ה-CPP העורפי.

ניתן להגדיר את ארגומנט type רק לסוגים האינטגרליים הבאים:

  • byte (רוחב של 8 סיביות)
  • int (רוחב 32 סיביות)
  • long (רוחב 64 סיביות)

JavaOnlyStableParcelable

JavaOnlyStableParcelable מסמנת הצהרה ניתנת לחלק (לא הגדרה) כיציבה כך שניתן להתייחס אליה מסוגי 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 מאפשר לך לעקוף את ההמחאה כאשר ה-parcelable שאתה מפנה כבר זמין בבטחה כחלק מה-SDK של Android.

@JavaOnlyStableParcelable
parcelable Data;

parcelable AnotherData {
    Data d; // OK
}

JavaDerive

JavaDerive יוצר אוטומטית שיטות לסוגים הניתנים לחלוקה ב-Java backend.

@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 T (ניסיוני AOSP), שולט אם נוצרת תמיכת ברירת המחדל של יישום גרסאות (עבור setDefaultImpl ). תמיכה זו כבר לא נוצרת כברירת מחדל על מנת לחסוך במקום.

JavaPassthrough

JavaPassthrough מאפשר ל-Java API שנוצר להערים עם הערת 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 אלא על ידי מהדר Java.

ניתן לצרף ביאור זה לכל ישות AIDL. הערה זו היא ללא הפעלה עבור קצה גבה שאינם Java.

מידה קבועה

FixedSize מסמן חלק מובנה כגודל קבוע. לאחר סימון, לא תתאפשר הוספת שדות חדשים לרכיב החבילה. כל השדות של החבילה חייבים להיות גם סוגים בגודל קבוע, כולל טיפוסים פרימיטיביים, רשימות, מערכים בגודל קבוע וחבילות אחרות המסומנות ב- FixedSize .

זה לא מספק שום ערובה על פני סיביות שונות ואין להסתמך עליו עבור תקשורת מעורבת בסיביות.

מתאר

Descriptor מציין בכוח את מתאר הממשק של ממשק.

package android.foo;

@Descriptor(value="android.bar.IWorld")
interface IHello {...}

המתאר של הממשק לעיל הוא android.bar.IWorld . אם הערת ה- Descriptor חסרה, המתאר יהיה android.foo.IHello .

זה שימושי לשינוי שם של ממשק שכבר פורסם. הפיכת המתאר של הממשק ששונה לשם זהה למתאר הממשק לפני שינוי השם מאפשר לשני הממשקים לדבר זה עם זה.

@הסתר בתגובות

מהדר AIDL מזהה את @hide בהערות ומעביר אותו לפלט Java כדי שה-metava לאסוף אותו. הערה זו מבטיחה שמערכת הבנייה של אנדרואיד יודעת שממשקי API של AIDL אינם ממשקי API של SDK.

@מבוטל בתגובות

מהדר AIDL מזהה את @deprecated בהערות כתג לזיהוי ישות AIDL שכבר אין להשתמש בה.

interface IFoo {
  /** @deprecated use bar() instead */
  void foo();
  void bar();
}

כל קצה אחורי מסמן ישויות שהוצאו משימוש בהערה/תכונה ספציפית לקצה, כך שקוד הלקוח יוזהר אם הוא מפנה את הישויות שהוצאו משימוש. לדוגמה, ההערה @Deprecated והתג @deprecated מצורפים לקוד שנוצר ב-Java.