يدعم 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 |
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
هذا التعليق التوضيحي غير متاح للواجهة الخلفية لـ 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>
بشكل متساوٍ، وهو بالفعل لاغٍ لأنه مؤشر قوي (قراءات CPP لا تزال تفرض البطلان، لكن النوع لا يزال 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
يعلن 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
إلى أن نوع AIDL المشروح هو جزء من واجهة غير SDK التي يمكن الوصول إليها للتطبيقات القديمة. راجع القيود المفروضة على الواجهات غير التابعة لـ SDK لمزيد من المعلومات حول واجهات برمجة التطبيقات المخفية.
لا يؤثر التعليق التوضيحي UnsupportedAppUsage
على سلوك التعليمات البرمجية التي تم إنشاؤها. يقوم التعليق التوضيحي فقط بتعليق فئة Java التي تم إنشاؤها باستخدام تعليق Java التوضيحي الذي يحمل نفس الاسم.
// in AIDL
@UnsupportedAppUsage
interface IFoo {...}
// in Java
@android.compat.annotation.UnsupportedAppUsage
public interface IFoo {...}
هذا أمر محظور بالنسبة للواجهات الخلفية غير Java.
دعم
يحدد التعليق التوضيحي Backing
نوع التخزين لنوع تعداد 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
بوضع علامة على إعلان قابل للتجزئة (وليس تعريفًا) على أنه مستقر بحيث يمكن الرجوع إليه من أنواع AIDL المستقرة الأخرى. هذا يشبه JavaOnlyStableParcelable
، لكن NdkOnlyStableParcelable
يضع علامة على إعلان قابل للتجزئة باعتباره مستقرًا لواجهة NDK الخلفية بدلاً من Java.
لاستخدام هذا الطرد: * يجب عليك تحديد ndk_header
. * يجب أن يكون لديك مكتبة NDK تحدد العناصر القابلة للتجزئة ويجب تجميع المكتبة في المكتبة. على سبيل المثال، في نظام البناء الأساسي على وحدة 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
تجاوز عملية التحقق عندما يكون العنصر القابل للتجزئة الذي تشير إليه متاحًا بالفعل بأمان كجزء من Android SDK.
@JavaOnlyStableParcelable
parcelable Data;
parcelable AnotherData {
Data d; // OK
}
JavaDeriv
يقوم JavaDerive
تلقائيًا بإنشاء طرق للأنواع القابلة للتجزئة في الواجهة الخلفية لـ Java.
@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
إضافة تعليقات توضيحية إلى 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)
في كود جافا الذي تم إنشاؤه.
يتم إصدار قيمة معلمة 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 من التقاطه. يضمن هذا التعليق أن نظام إنشاء Android يعرف أن واجهات برمجة تطبيقات AIDL ليست واجهات برمجة تطبيقات SDK.
@محذوف في التعليقات
يتعرف مترجم AIDL على @deprecated
في التعليقات كعلامة لتحديد كيان AIDL الذي لم يعد من المفترض استخدامه.
interface IFoo {
/** @deprecated use bar() instead */
void foo();
void bar();
}
تحدد كل واجهة خلفية الكيانات المهملة بتعليق توضيحي/سمة خاصة بالواجهة الخلفية بحيث يتم تحذير رمز العميل إذا كان يشير إلى الكيانات المهملة. على سبيل المثال، يتم إرفاق التعليق @Deprecated
والعلامة @deprecated
بالكود الذي تم إنشاؤه بواسطة Java.