التعليقات التوضيحية في AIDL

يدعم AIDL التعليقات التوضيحية التي تمنح المحول البرمجي AIDL معلومات إضافية حول العنصر المشروح ، والذي يؤثر أيضًا على كود كعب الروتين الذي تم إنشاؤه.

بناء الجملة مشابه لذلك في 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
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. هذا لأنه ، في 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>>> Optional <T> >> (أو std::unique_ptr<std::vector<std::unique_ptr<T>>> في حالة الواجهة الخلفية CPP لنظام Android 11 أو أقل).

هناك استثناء لهذا التعيين. عندما تكون T عبارة عن IBinder أو واجهة @nullable ، فإنnullable هي no-op. بعبارة أخرى ، يتم تعيين كل من @nullable IBinder و IBinder بشكل متساوٍ إلى android::sp<IBinder> ، والذي يعد لاغياً بالفعل لأنه مؤشر قوي (لا تزال قراءة CPP تفرض إلغاء ، ولكن النوع لا يزال android::sp<IBinder> ).

بدءًا من Android T (تجريبي AOSP) ، يمكن استخدام @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 أنه يمكن استخدام نوع معرف من قبل المستخدم (واجهة ، لا يتجزأ ، وتعداد) عبر مجالات النظام والمورد. راجع 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 لمزيد من المعلومات حول واجهات برمجة التطبيقات المخفية.

لا يؤثر التعليق التوضيحي UnsupportedAppUsage على سلوك الكود الذي تم إنشاؤه. التعليق التوضيحي يعلق فقط على فئة Java التي تم إنشاؤها مع تعليق Java التوضيحي بنفس الاسم.

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

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

هذا هو no-op للخلفيات التي ليست Java.

دعم

يحدد التعليق التوضيحي للنسخ نوع التخزين لنوع تعداد Backing .

@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 بت)

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 تجاوز التحقق عندما يكون العنصر الذي تشير إليه متاحًا بالفعل بأمان كجزء من Android SDK.

@JavaOnlyStableParcelable
parcelable Data;

parcelable AnotherData {
    Data d; // OK
}

جافا ديريف

JavaDerive تلقائيًا بإنشاء طرق للأنواع القابلة للتجزئة في واجهة Java الخلفية.

@JavaDerive(equals = true, toString = true)
parcelable Data {
  int number;
  String str;
}

يتطلب التعليق التوضيحي معلمات إضافية للتحكم في ما يتم إنشاؤه. المعلمات المدعومة هي:

  • equals=true يولد equals وطرق hashCode .
  • تولد toString toString=true طريقة toString التي تطبع اسم النوع والحقول. على سبيل المثال: Data{number: 42, str: foo}

جافا

JavaDefault ، المضاف في Android T (تجريبي AOSP) ، في ما إذا كان دعم إصدار التنفيذ الافتراضي قد تم إنشاؤه (لـ 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. هذا التعليق التوضيحي غير متاح للخلفيات التي لا تستخدم جافا.

حجم ثابت

FixedSize يمثل لا يتجزأ منظم كحجم ثابت. بمجرد وضع علامة على الطرد ، لن يُسمح بإضافة حقول جديدة إليه. يجب أيضًا أن تكون جميع حقول الطرود من الأنواع ذات الحجم الثابت ، بما في ذلك الأنواع الأولية ، والتعدادات ، والمصفوفات ذات الحجم الثابت ، وغيرها من العناصر المميزة FixedSize .

لا يوفر هذا أي ضمان عبر شهود مختلفين ولا ينبغي الاعتماد عليه للتواصل بين الشهود المختلط.

الواصف

يحدد الواصف بالقوة Descriptor الواجهة للواجهة.

package android.foo;

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

واصف الواجهة أعلاه هو android.bar.IWorld . إذا كان التعليق التوضيحي Descriptor مفقودًا ، فسيكون الموصف هو android.foo.IHello .

هذا مفيد لإعادة تسمية واجهة منشورة بالفعل. جعل واصف الواجهة المعاد تسميتها هو نفسه واصف الواجهة قبل إعادة التسمية يسمح للواجهتين بالتحدث مع بعضهما البعض.

@ إخفاء في التعليقات

يتعرف برنامج التحويل البرمجي @hide على @ إخفاء في التعليقات ويمررها إلى إخراج جافا حتى يلتقطها ميتالافا. يضمن هذا التعليق أن نظام إنشاء Android يعرف أن واجهات برمجة تطبيقات AIDL ليست واجهات برمجة تطبيقات SDK.

deprecated في التعليقات

يتعرف برنامج التحويل البرمجي @deprecated علىdeprecated في التعليقات كعلامة لتحديد كيان AIDL الذي لا ينبغي استخدامه بعد الآن.

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

تشير كل خلفية إلى الكيانات المهملة بتعليق توضيحي / سمة خاصة بالواجهة الخلفية بحيث يتم تحذير رمز العميل إذا كان يشير إلى الكيانات المهملة. على سبيل المثال ، يتم إرفاق التعليق التوضيحي @Deprecated وعلامة @deprecated البرمجية التي تم إنشاؤها بواسطة Java.