تتيح لغة 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
تعلن 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>
في الإصدار 11 من نظام التشغيل Android أو الإصدارات الأقدم، وبـ std::optional<T>
في الإصدار 12 من نظام التشغيل Android أو الإصدارات الأحدث.
في الخلفية الأصلية لحزمة تطوير البرامج (NDK)، يتم دائمًا ربط @nullable T
بـ std::optional<T>
.
في الخلفية المستندة إلى Rust، يتم دائمًا ربط @nullable T
بـ Option<T>
.
بالنسبة إلى نوع يشبه القائمة L
مثل T[]
أو List<T>
، يتم ربط @nullable L
بـ std::optional<std::vector<std::optional<T>>>
(أو std::unique_ptr<std::vector<std::unique_ptr<T>>>
في حال كان الخادم الخلفي لخدمة مقارنة الأسعار مخصّصًا للإصدار 11 من نظام التشغيل Android أو إصدار أقدم).
هناك استثناء لهذه العملية. عندما يكون T
هو IBinder
أو واجهة AIDL، يكون @nullable
بلا تأثير لجميع الأنظمة الخلفية باستثناء Rust. بمعنى آخر، يتم ربط كل من
@nullable IBinder
وIBinder
بشكل متساوٍ بـ android::sp<IBinder>
، وهو
قابل للقيم الخالية لأنّه مؤشر قوي (لا تزال عمليات القراءة في CPP
تفرض إمكانية القيم الخالية، ولكن يظل النوع android::sp<IBinder>
). في Rust،
تكون هذه الأنواع nullable
فقط إذا تم وضع التعليق التوضيحي @nullable
عليها. ويتم ربطها بـ Option<T>
في حال إضافة تعليق توضيحي إليها.
بدءًا من 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
عن إمكانية استخدام نوع محدّد من قِبل المستخدم (واجهة، وقابل للتجزئة، وقائمة تعداد) في جميع نطاقات النظام والمورّد. راجِع لغة تعريف واجهة Android (AIDL) لطبقات تجريد الأجهزة (HAL) لمزيد من المعلومات حول إمكانية التشغيل التفاعلي بين النظام والمورّد.
لا تغيّر التعليقات التوضيحية توقيع النوع، ولكن عند ضبطها، يتم وضع علامة على مثيل النوع على أنّه ثابت حتى يتمكّن من الانتقال بين عمليات المورّد والنظام.
لا يمكن إرفاق التعليق التوضيحي إلا بتعريفات الأنواع التي يحدّدها المستخدم كما هو موضّح هنا:
@VintfStability
interface IFoo {
....
}
@VintfStability
parcelable Data {
....
}
@VintfStability
enum Type {
....
}
عند إضافة التعليق التوضيحي VintfStability
إلى أحد الأنواع، يجب إضافة التعليق التوضيحي نفسه إلى أي نوع آخر تتم الإشارة إليه في النوع. في المثال التالي، يجب إضافة التعليق التوضيحي VintfStability
إلى كل من Data
وIBar
.
@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 {...}
لا يتم تنفيذ أي عملية في الخلفيات غير المستندة إلى 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
تجاهل عملية التحقّق عندما يكون العنصر القابل للتسلسل الذي تشير إليه متاحًا بأمان كجزء من حزمة تطوير البرامج (SDK) لنظام التشغيل Android.
@JavaOnlyStableParcelable
parcelable Data;
parcelable AnotherData {
Data d; // OK
}
JavaDerive
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 إلى واجهة برمجة التطبيقات التي تم إنشاؤها بلغة 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.
RustDerive
تنفّذ RustDerive
تلقائيًا السمات لأنواع Rust التي تم إنشاؤها.
تتطلّب التعليقات التوضيحية مَعلمات إضافية للتحكّم في المحتوى الذي سيتم إنشاؤه. المَعلمات المتوافقة هي:
Copy=true
Clone=true
Ord=true
PartialOrd=true
Eq=true
PartialEq=true
Hash=true
للحصول على توضيحات حول هذه السمات، يُرجى الانتقال إلى https://doc.rust-lang.org.
FixedSize
تضع FixedSize
علامة على عنصر قابل للتسلسل كحجم ثابت. بعد وضع علامة على العنصر، لن يُسمح بإضافة حقول جديدة إليه. يجب أن تكون جميع حقول الكائن القابل للتسلسل من أنواع ذات حجم ثابت، بما في ذلك الأنواع الأولية والتعدادات والمصفوفات ذات الحجم الثابت والكائنات الأخرى القابلة للتسلسل التي تم وضع العلامة FixedSize
عليها.
ولا يقدّم هذا الخيار أي ضمانات على مستوى مختلف أنواع البتات، ولا يجب الاعتماد عليه في التواصل بين أنواع البتات المختلفة.
الواصف
تحدّد السمة Descriptor
بشكل إجباري واصف الواجهة لواجهة معيّنة.
package android.foo;
@Descriptor(value="android.bar.IWorld")
interface IHello {...}
واصف هذه الواجهة هو android.bar.IWorld
. في حال عدم توفّر التعليق التوضيحي
Descriptor
، سيكون الوصف
android.foo.IHello
.
ويكون ذلك مفيدًا لإعادة تسمية واجهة تم نشرها من قبل. إنّ جعل وصف الواجهة التي تمت إعادة تسميتها مطابقًا لوصف الواجهة قبل إعادة التسمية يتيح للواجهتين التواصل مع بعضهما.
@hide in comments
يتعرّف برنامج ترجمة AIDL على @hide
في التعليقات وينقلها إلى مخرجات Java لكي تلتقطها أداة Metalava. يضمن هذا التعليق أن يعرف نظام الإصدار في Android أنّ واجهات برمجة التطبيقات AIDL ليست واجهات برمجة تطبيقات لحزمة تطوير البرامج (SDK).
@deprecated في التعليقات
يتعرّف برنامج ترجمة AIDL على @deprecated
في التعليقات كعلامة لتحديد عنصر AIDL يجب التوقف عن استخدامه.
interface IFoo {
/** @deprecated use bar() instead */
void foo();
void bar();
}
يضع كل نظام خلفي علامة على الكيانات المتوقّفة نهائيًا باستخدام تعليق توضيحي أو سمة خاصة بالنظام الخلفي، وذلك لتنبيه رمز العميل في حال الإشارة إلى الكيانات المتوقّفة نهائيًا. على سبيل المثال، يتم إرفاق التعليق التوضيحي @Deprecated
والعلامة @deprecated
بالرمز البرمجي الذي تم إنشاؤه بلغة Java.