تتيح لغة AIDL التعليقات التوضيحية التي تمنح مُجمِّع AIDL معلومات إضافية عن العنصر الذي يحتوي على تعليق توضيحي، ما يؤثر أيضًا في رمز الرمز المرجعي الذي تم إنشاؤه.
تتشابه بنية هذه الأوامر مع بنية Java:
@AnnotationName(argument1=value, argument2=value) AidlEntity
في هذه الحالة، AnnotationName
هو اسم التعليق التوضيحي، وAidlEntity
هو
عنصر لغة تعريف واجهة نظام Android (AIDL) مثل interface Foo
أو void method()
أو int arg
. يتم إرفاق annotation بالعنصر الذي يليه.
يمكن أن تحتوي بعض التعليقات التوضيحية على وسيطات تم ضبطها داخل الأقواس، كما هو موضّح أعلاه. لا تحتاج التعليقات التوضيحية التي لا تحتوي على وسيطة إلى قوس. مثلاً:
@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>
.
في الخلفية في 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>>>
في حال استخدام الخلفية في خدمة مقارنة الأسعار
لنظام التشغيل Android 11 أو الإصدارات الأقدم).
هناك استثناء لهذا الربط. عندما يكون T
IBinder
أو واجهة AIDL، يكون @nullable
غير فعّال لجميع الخلفيات باستثناء
Rust. بعبارة أخرى، يتم ربط كل من
@nullable IBinder
وIBinder
بالتساوي بـ android::sp<IBinder>
، وهو
يمكن أن يكون خاليًا من القيمة لأنّه مُشير قوي (لا تزال قراءات لغة C++ تفرض
عدم السماح بقيمة خالية، ولكن النوع لا يزال 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 لخلفية String
. وكما يشير اسمه، لا يُستخدَم التعليق التوضيحي مع الخلفيات الأخرى.
على وجه التحديد، يكون String
دائمًا بترميز UTF16 في الخلفية في Java وUTF8 في NDK
الخلفية.
يمكن إرفاق هذا التعليق التوضيحي في أي مكان يمكن فيه استخدام نوع String
،
بما في ذلك قيم الإرجاع والمَعلمات وإعلانات الثوابت وحقول parcelable.
بالنسبة إلى الخلفية في لغة C++، يتم ربط @utf8InCpp String
في AIDL بـ std::string
، في حين يتم ربط
String
بدون التعليق التوضيحي بـ android::String16
حيث يتم استخدام UTF16.
يُرجى العلم أنّ وجود التعليق التوضيحي utf8InCpp
لا يغيّر طريقة إرسال سلاسل العلامات عبر الشبكة. يتم دائمًا نقل السلاسل بتنسيق UTF16
عبر السلك. يتم تحويل سلسلة utf8InCpp
التي تحتوي على تعليقات توضيحية إلى UTF16 قبل
إرسالها. عند تلقّي سلسلة، يتم تحويلها من UTF16 إلى UTF8 إذا
تمّت إضافة تعليق توضيحي لها على أنّها utf8InCpp
.
ثبات VintfStability
تُعلِن العلامة VintfStability
أنّه يمكن استخدام نوع يحدّده المستخدم (interface وparcelable
و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
إلا باستخدام نوع وحدة Soong aidl_interface
، مع ضبط السمة
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, }
في الخلفية في لغة C++، يؤدي ذلك إلى إنشاء فئة قائمة بقيم ثابتة من النوع int32_t
.
enum class Color : int32_t {
RED = 0,
BLUE = 1,
}
في حال حذف التعليق التوضيحي، يتم افتراض أنّ type
هي byte
، والتي يتم ربطها
بـ int8_t
في الخلفية في "المعالجة المحدودة للصور".
يمكن ضبط الوسيطة 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 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
لتمييز قطعة أرض قابلة للتقسيم بحجم ثابت. بعد وضع علامة على العنصر، لن يُسمح
بإضافة حقول جديدة إليه. يجب أن تكون جميع حقول
العنصر القابل للنقل من أنواع ذات حجم ثابت، بما في ذلك الأنواع الأساسية،
والقوائم المحددة، والمصفوفات ذات الحجم الثابت، والعناصر القابلة للنقل الأخرى التي تم وضع علامة FixedSize
عليها.
ولا يقدّم هذا الإجراء أي ضمان على مستوى وحدات البت المختلفة، ولا يجب الاعتماد عليه في عمليات التواصل التي تستخدم وحدات بت مختلطة.
الوصف
Descriptor
يحدِّد بشكلٍ قسري وصف الواجهة لواجهة معيّنة.
package android.foo;
@Descriptor(value="android.bar.IWorld")
interface IHello {...}
واصف هذه الواجهة هو android.bar.IWorld
. إذا لم يكن هناك تعليق توضيحي
Descriptor
، سيكون الواصف
android.foo.IHello
.
يكون هذا الإجراء مفيدًا لإعادة تسمية واجهة سبق نشرها. جعل واصف الواجهة المُعاد تسميتها مماثلاً لواصف الواجهة قبل إعادة التسمية يمكن للواجهتين التحدث مع بعضها البعض.
@hide في التعليقات
يتعرّف مُجمِّع AIDL على @hide
في التعليقات ويمرّره من خلال
إلى إخراج Java لكي تلتقطه أداة Metalava. يضمن هذا التعليق أن يعرف نظام ملف APK لنظام Android أنّ واجهات برمجة التطبيقات AIDL ليست واجهات برمجة تطبيقات حزمة تطوير البرامج (SDK).
@deprecated في التعليقات
يتعرّف مُجمِّع AIDL على @deprecated
في التعليقات كعلامة لتحديد
كيان AIDL الذي يجب عدم استخدامه بعد الآن.
interface IFoo {
/** @deprecated use bar() instead */
void foo();
void bar();
}
يضع كل نظام أساسي علامة على العناصر المتوقّفة نهائيًا باستخدام تعليق توضيحي أوسمة
خاصة بالنظام الأساسي حتى يتم تحذير رمز العميل إذا كان يشير إلى العناصر
التي تم إيقافها نهائيًا. على سبيل المثال، يتم إرفاق التعليق التوضيحي @Deprecated
والعلامة @deprecated
بالرمز الذي تم إنشاؤه باستخدام Java.