تتيح لغة 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
يشير الرمز 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 لنظام CPP
الخلفي. وكما يشير اسمه، لا يُستخدَم التعليق التوضيحي مع الخلفيات الأخرى.
على وجه التحديد، يكون 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 لواجهة HAL لمعرفة مزيد من المعلومات حول إمكانية التشغيل التفاعلي بين النظام والمورّد.
لا يغيّر التعليق التوضيحي توقيع النوع، ولكن عند ضبطه، يتم وضع علامة على مثيل النوع على أنّه ثابت حتى يمكن نقله عبر عمليات المورّد والنظام.
لا يمكن إرفاق التعليق التوضيحي إلا ببيانات أنواع محدّدة من قِبل المستخدم كما هو موضّح هنا:
@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
في الخلفية في تنسيق CPP.
لا يمكن ضبط الوسيطة type
إلا على الأنواع الصحيحة التالية:
-
byte
(بعرض 8 بت) -
int
(بعرض 32 بت) -
long
(بعرض 64 بت)
NdkOnlyStableParcelable
يضع الرمز NdkOnlyStableParcelable
علامة على بيان قابل للتقسيم (وليس التعريف)
كثابت حتى يمكن الإشارة إليه من أنواع AIDL الثابتة الأخرى. يشبه هذا الرمز JavaOnlyStableParcelable
، ولكن يضع NdkOnlyStableParcelable
علامة على بيان قابل للتقسيم على أنّه ثابت لنظام NDK العميق بدلاً من Java.
لاستخدام هذه الميزة:
- يجب تحديد
ndk_header
. - يجب أن تتوفّر لديك مكتبة NDK تحدّد العنصر القابل للتعبئة، ويجب compiling المكتبة في المكتبة. على سبيل المثال، في نظام الإنشاء الأساسي في وحدة
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.
@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.
RustDerive
تنفِّذ RustDerive
تلقائيًا سمات أنواع Rust التي تم إنشاؤها.
يتطلّب التعليق التوضيحي مَعلمات إضافية للتحكّم في ما ينبغي إنشاؤه. في ما يلي المَعلمات المتوافقة:
Copy=true
Clone=true
Ord=true
PartialOrd=true
Eq=true
PartialEq=true
Hash=true
للحصول على تفسيرات لهذه السمات، يُرجى الاطّلاع على https://doc.rust-lang.org.
FixedSize
يُستخدَم الرمز FixedSize
لتمييز قطعة أرض قابلة للتقسيم بحجم ثابت. بعد وضع العلامة، لن يُسمح بإضافة حقول جديدة إلى العنصر
parcelable. يجب أن تكون جميع حقول
العنصر القابل للنقل من أنواع ذات حجم ثابت، بما في ذلك الأنواع الأساسية،
والقوائم المحددة، والمصفوفات ذات الحجم الثابت، والعناصر القابلة للنقل الأخرى التي تم وضع علامة 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.