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

utf8InCpp

utf8InCpp מצהיר String מיוצגת בפורמט UTF8 עבור ה-CPP העורפי. כפי שהשם שלה מעיד, ההערה היא ללא הפעלה עבור קצה אחורי אחרים. באופן ספציפי, 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 Soong, כאשר מאפיין 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 סיביות)

NdkOnlyStableParcelable

NdkOnlyStableParcelable מסמן הצהרה ניתנת לחלוקה (לא הגדרה) כיציבה כך שניתן להתייחס אליה מסוגי AIDL יציבים אחרים. זה כמו JavaOnlyStableParcelable , אבל NdkOnlyStableParcelable מסמן הצהרה ניתנת לחלוקה כיציבה עבור ה-NDK העורפי במקום עבור Java.

כדי להשתמש ב-parcelable זה: * עליך לציין ndk_header . * עליך להיות בעל ספריית NDK המציינת את ה-parcelable והספרייה חייבת להיות מורכבת בספרייה. לדוגמה, במערכת בניית הליבה במודול cc_* , השתמש static_libs או shared_libs . עבור aidl_interface , הוסף את הספרייה תחת additional_shared_libraries ב- Android.bp .

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 , שנוספה באנדרואיד 13, שולטת אם נוצרת תמיכת ברירת המחדל של יישום גרסאות (עבור 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 כדי לאסוף את metalava. הערה זו מבטיחה שמערכת הבנייה של אנדרואיד יודעת שממשקי API של AIDL אינם ממשקי API של SDK.

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

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

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

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