يمكن أن يساعدك استخدام أدوات فحص الرموز، مثل lint، في العثور على
المشكلات وتحسين التعليمات البرمجية، ولكن أدوات الفحص يمكنها استنتاج الكثير فقط. معرّفات موارد Android
على سبيل المثال، يمكنك استخدام int
لتحديد السلاسل والرسومات والألوان وأنواع الموارد الأخرى،
لذلك لا يمكن لأدوات الفحص معرفة الوقت الذي حددت فيه مورد سلسلة حيث ينبغي
حددت لونًا. يعني هذا الموقف أنّه قد يتم عرض تطبيقك بشكل غير صحيح أو قد يتعذّر تشغيله على الإطلاق،
حتى عند استخدام فحص الرموز
تتيح لك التعليقات التوضيحية تقديم تلميحات لأدوات فحص التعليمات البرمجية، مثل Lint، للمساعدة في اكتشاف مشكلات التعليمات البرمجية الأكثر دقة. تتم إضافة التعليقات التوضيحية كعلامات بيانات وصفية ترفقها بالمتغيرات، والقيم التي يتم إرجاعها للتحقق من قيم إرجاع الطريقة والمعلمات التي تم تمريرها والمتغيرات المحلية والحقول. يمكن أن تساعدك التعليقات التوضيحية في رصد مشاكل مثل استثناءات المؤشر الفارغ وتعارضات أنواع الموارد.
يتيح Android استخدام مجموعة متنوعة من التعليقات التوضيحية من خلال
مكتبة التعليقات التوضيحية في Jetpack
يمكنك الوصول إلى المكتبة من خلال
androidx.annotation
طرد.
ملاحظة: إذا كانت الوحدة تعتمد على معالِج تعليقات توضيحية،
يجب استخدام إعدادات التبعية kapt
أو ksp
للغة Kotlin.
أو ضبط التبعية annotationProcessor
لـ Java لإضافة ذلك
والتبعية.
إضافة تعليقات توضيحية إلى مشروعك
لتفعيل التعليقات التوضيحية في مشروعك، أضِف androidx.annotation:annotation
والاعتمادية على مكتبتك أو تطبيقك. يتم التحقق من أي تعليقات توضيحية تضيفها عند تشغيل التعليمة البرمجية
الفحص أو مهمة lint
.
إضافة تبعية مكتبة التعليقات التوضيحية في Jetpack
تم نشر مكتبة التعليقات التوضيحية في Jetpack على
مستودع Maven من Google:
لإضافة مكتبة Jetpack Anotations إلى مشروعك، يجب تضمين ما يلي:
السطر في المجموعة dependencies
من build.gradle
أو
ملف build.gradle.kts
:
Kotlin
dependencies { implementation("androidx.annotation:annotation:1.8.2") }
Groovy
dependencies { implementation 'androidx.annotation:annotation:1.8.2' }
إذا استخدمت التعليقات التوضيحية في وحدة المكتبة الخاصة بك، فسيتم تضمين التعليقات التوضيحية كجزء من
عنصر أرشيف Android (AAR) بتنسيق XML في ملف annotations.zip
. إضافة
لا تقدم تبعية androidx.annotation
أي تبعية لأي مستخدم من مستخدمي المراحل التالية
في مكتبتك
ملاحظة: إذا كنت تستخدم مكتبات Jetpack الأخرى،
قد لا تحتاج إلى إضافة تبعية androidx.annotation
. لأن العديد من الأشخاص
تعتمد مكتبات Jetpack على مكتبة التعليقات التوضيحية، وقد يكون بإمكانك الوصول إلى
التعليقات التوضيحية.
للحصول على قائمة كاملة بالتعليقات التوضيحية المضمّنة في مستودع Jetpack، يمكنك الاطّلاع على
مكتبة التعليقات التوضيحية في Jetpack
المرجع أو استخدام ميزة الإكمال التلقائي لعرض الخيارات المتاحة
عبارة import androidx.annotation.
.
إجراء عمليات فحص للرموز البرمجية
لبدء فحص الرمز من "استوديو Android"، والذي يتضمّن التحقّق من صحة التعليقات التوضيحية فحص الوبر التلقائي، حدد تحليل > افحص الرمز البرمجي من القائمة. يعرض "استوديو Android" رسائل التعارضات للإبلاغ عن المشاكل المحتمَلة عندما يتضمّن رمزك مع التعليقات التوضيحية واقتراح حلول ممكنة.
ويمكنك أيضًا فرض التعليقات التوضيحية عن طريق تشغيل
lint
باستخدام سطر الأوامر. رغم أنّ هذا الإجراء قد يكون مفيدًا للإبلاغ عن المشاكل
باستخدام خادم تكامل مستمر، لن تفرض المهمة lint
قيمًا خالية
التعليقات التوضيحية (الموضّحة في القسم التالي) ذلك باستخدام "استوديو Android" فقط. لمزيد من المعلومات،
معلومات حول تمكين وتشغيل أداة Lint
عمليات الفحص، راجع تحسين الرمز باستخدام أداة Lint
عمليات التحقق.
على الرغم من أنّ التعارضات التوضيحية تؤدي إلى تحذيرات، فإنّ هذه التحذيرات لا تمنع تطبيقك. من التجميع.
تعليقات توضيحية فارغة
يمكن أن تكون التعليقات التوضيحية للقيم الخالية مفيدة في رمز Java لفرض ما إذا كان يمكن أن تكون القيم فارغة. وهي أقل فائدة في التعليمات البرمجية Kotlin، حيث تم تضمين قواعد قابلية القيم الفارغة في Kotlin والتي يتم فرضها على وقت التجميع.إضافة @Nullable
@NonNull
تعليقات توضيحية
للتحقق من عدم جدوى متغير معين أو معلمة أو عرض قيمة معينة. @Nullable
يشير التعليق التوضيحي إلى متغير أو معلمة أو عرض قيمة يمكن أن تكون فارغة.
تشير @NonNull
إلى متغيّر أو مَعلمة أو قيمة معروضة لا يمكن أن تكون فارغة.
على سبيل المثال، إذا تم تمرير متغير محلي يحتوي على قيمة فارغة كمعلمة إلى طريقة
مع التعليق التوضيحي @NonNull
المرفق بهذه المَعلمة، يؤدي إنشاء الرمز إلى إنشاء
تحذير يشير إلى تعارض غير فارغ. كما أن محاولة الإشارة إلى نتيجة
تم وضع علامة @Nullable
عليها بدون التحقّق أولاً مما إذا كانت النتيجة خالية من القيم.
تحذير بالمخالفة. استخدام @Nullable
فقط للقيمة المعروضة لطريقة ما
إذا كان يجب تحديد قيمة فارغة في كل استخدام للطريقة بشكل صريح.
يوضح المثال التالي قابلية القيم الفارغة عمليًا. لا يستفيد مثال التعليمة البرمجية لـ Kotlin من
التعليق التوضيحي @NonNull
لأنّه تتم إضافته تلقائيًا إلى رمز البايت الذي تم إنشاؤه
عند تحديد نوع غير قابل للقيم الفارغة. يستفيد مثال Java من التعليق التوضيحي @NonNull
.
في المَعلمتَين context
وattrs
للتأكّد من أنّ قيم المَعلمات التي تم ضبطها
ليست فارغة. يتحقّق أيضًا من أنّ طريقة onCreateView()
نفسها لا تعرض قيمة فارغة:
Kotlin
... /** Annotation not used because of the safe-call operator(?)**/ override fun onCreateView( name: String?, context: Context, attrs: AttributeSet ): View? { ... } ...
Java
import androidx.annotation.NonNull; ... /** Add support for inflating the <fragment> tag. **/ @NonNull @Override public View onCreateView(String name, @NonNull Context context, @NonNull AttributeSet attrs) { ... } ...
تحليل القيم الفارغة
يتيح "استوديو Android" إجراء تحليل القيم الفارغة للاستنتاج تلقائيًا. وإدراج تعليقات توضيحية للعدم في التعليمة البرمجية. عمليات فحص تحليل قابلية القيم الفارغة العقود عبر التسلسلات الهرمية للطريقة في التعليمة البرمجية لاكتشاف:
- طرق الاتصال التي يمكن أن تعرض قيمة خالية.
- الطرق التي يجب ألا تعرض قيمة خالية.
- هي المتغيّرات، مثل الحقول والمتغيّرات المحلية والمَعلمات التي يمكن أن خالية.
- فالمتغيرات، مثل الحقول والمتغيّرات المحلية والمعلَمات التي لا يمكنها على قيمة فارغة.
ثم يقوم التحليل تلقائيًا بإدراج التعليقات التوضيحية الفارغة المناسبة في المواقع التي تم اكتشافها.
لإجراء تحليل لقابلية القيم الفارغة في "استوديو Android"، اختَر تحليل >
استنتاج القيم الفارغة: يُدرج "استوديو Android" التعليقات التوضيحية @Nullable
و@NonNull
لنظام التشغيل Android في
المواقع التي تم اكتشافها في رمزك. بعد تشغيل تحليل فارغ، من الأفضل التحقق من
التعليقات التوضيحية التي تم إدخالها.
ملاحظة: عند إضافة تعليقات توضيحية للعدم، قد يكون الإكمال التلقائي
اقتراح IntelliJ
@Nullable
و
تعليقات @NotNull
التوضيحية بدلاً من التعليقات التوضيحية الفارغة في Android
وقد يستورد المكتبة المقابلة تلقائيًا. ومع ذلك، يمكن استخدام Android Studio
يبحث مدقق Lint فقط عن التعليقات التوضيحية الفارغة في Android. عند إثبات ملكية
التعليقات التوضيحية، فتأكد من أن مشروعك يستخدم التعليقات التوضيحية الفارغة في Android حتى
يمكن أن يُعلمك أداة فحص الوبر بشكل صحيح أثناء فحص الرمز.
التعليقات التوضيحية للمراجع
يمكن أن يكون التحقق من أنواع الموارد مفيدًا لأنه يتم تمرير مراجع Android إلى الموارد، مثل الموارد القابلة للرسم والسلسلة، كأعداد صحيحة.
يشير ذلك المصطلح إلى رمز برمجي يتوقع أن تشير إحدى المعلَمات إلى نوع معيّن من الموارد، مثل String
.
إلى نوع المرجع المتوقع int
، ولكنه يشير في الواقع إلى نوع مرجعي مختلف
نوع المورد، مثل مورد R.string
.
على سبيل المثال، يمكنك إضافة تعليقات @StringRes
التوضيحية إلى
تحقَّق مما إذا كانت معلَمة المورد تحتوي على مرجع R.string
، كما هو موضّح هنا:
Kotlin
abstract fun setTitle(@StringRes resId: Int)
Java
public abstract void setTitle(@StringRes int resId)
أثناء فحص الرمز، ينشئ التعليق التوضيحي تحذيرًا إذا كانت الإحالة باستخدام R.string
لا يتم تمريرها في المعلمة.
يمكن أن تكون التعليقات التوضيحية لأنواع الموارد الأخرى، مثل @DrawableRes
و@DimenRes
و@ColorRes
و@InterpolatorRes
وتتم إضافتها باستخدام تنسيق التعليقات التوضيحية نفسه ويتم تشغيلها أثناء فحص الرموز.
إذا كانت المعلمة
يتيح استخدام أنواع متعددة من الموارد، يمكنك وضع أكثر من تعليق توضيحي واحد لنوع الموارد على
. استخدام "@AnyRes
"
للإشارة إلى أن المعلمة التي تم التعليق عليها يمكن أن تكون أي نوع من موارد R
.
على الرغم من أنّه يمكنك استخدام @ColorRes
لتحديد أنّ
يجب أن تكون معلمة اللون أو عددًا صحيحًا للون (في RRGGBB
أو
تنسيق AARRGGBB
) لم يتم التعرّف عليه كمورد للألوان. يمكنك بدلاً من ذلك استخدام التعليق التوضيحي @ColorInt
لتنفيذ ما يلي:
إلى أن المعلمة يجب أن تكون عددًا صحيحًا للّون. ستضع أدوات التصميم علامة على أي رمز غير صحيح
يمرر معرف مورد لون مثل android.R.color.black
، بدلاً من عدد صحيح للون،
إلى طرق تتضمن تعليقات توضيحية.
التعليقات التوضيحية لسلاسل المحادثات
تتحقق التعليقات التوضيحية لسلسلة المحادثات مما إذا كان يتم استدعاء طريقة من نوع معين من سلسلة محادثات. سلسلة المحادثات التالية التعليقات التوضيحية متاحة:
تتعامل أدوات التصميم مع @MainThread
إنّ تعليقات @UiThread
التوضيحية قابلة للتبديل، وبالتالي يمكنك استدعاء @UiThread
.
من الطرق @MainThread
والعكس صحيح. ولكن من الممكن أن تكون واجهة المستخدم
أن تكون سلسلة المحادثات مختلفة عن سلسلة التعليمات الرئيسية، في حال كانت تطبيقات النظام ذات طرق عرض متعددة
في سلاسل محادثات مختلفة. ولذلك، يجب إضافة تعليقات توضيحية على الطرق المرتبطة بالتسلسل الهرمي لطريقة عرض التطبيق.
مع @UiThread
وإضافة تعليقات توضيحية إلى الطرق المرتبطة بدورة حياة التطبيق فقط
@MainThread
إذا كانت جميع الطرق في إحدى الفئات تتشارك متطلبات سلاسل المحادثات نفسها، يمكنك إضافة سلسلة محادثات واحدة. التعليق التوضيحي إلى الفئة للتحقق من أن جميع الطرق في الفئة يتم استدعاؤها من نفس النوع .
من الاستخدامات الشائعة للتعليقات التوضيحية لسلسلة المحادثات التحقق من صحة تلك الطرق أو الفئات التي تحتوي على تعليقات توضيحية
لا يتم استدعاء الدالة @WorkerThread
إلا من سلسلة محادثات مناسبة في الخلفية.
التعليقات التوضيحية لقيود القيمة
يمكنك استخدام @IntRange
@FloatRange
و
تعليقات @Size
التوضيحية على
للتحقق من صحة قيم المعلمات التي تم تمريرها. كل من @IntRange
و@FloatRange
تكون أكثر فائدة عند تطبيقها على المعاملات التي يُرجح أن يخطئ المستخدمون فيها في النطاق.
يتحقّق التعليق التوضيحي @IntRange
من أنّ عددًا صحيحًا أو معلَمة طويلة.
ضمن نطاق محدد. يشير المثال التالي إلى أنّ السمة alpha
على قيمة عدد صحيح من 0 إلى 255:
Kotlin
fun setAlpha(@IntRange(from = 0, to = 255) alpha: Int) { ... }
Java
public void setAlpha(@IntRange(from=0,to=255) int alpha) { ... }
يتحقّق التعليق التوضيحي @FloatRange
مما إذا كانت المَعلمة عائمة أو مزدوجة
ضمن نطاق محدد من قيم النقاط العائمة. يشير المثال التالي إلى أنّ
يجب أن تحتوي مَعلمة alpha
على قيمة عائمة تتراوح بين 0.0 و1.0:
Kotlin
fun setAlpha(@FloatRange(from = 0.0, to = 1.0) alpha: Float) {...}
Java
public void setAlpha(@FloatRange(from=0.0, to=1.0) float alpha) {...}
يتحقّق التعليق التوضيحي @Size
من حجم مجموعة أو
صفيفة أو طول سلسلة. يمكن استخدام التعليق التوضيحي @Size
للتأكّد
في الصفات التالية:
- الحد الأدنى للحجم، مثل
@Size(min=2)
- الحد الأقصى للحجم، مثل
@Size(max=2)
- الحجم الدقيق، مثل
@Size(2)
- رقم يجب أن يكون المقاس من مضاعفاته، مثل
@Size(multiple=2)
على سبيل المثال: @Size(min=1)
يتحقّق ممّا إذا كانت إحدى المجموعات فارغة أم لا، و@Size(3)
يتأكد من أن الصفيفة تحتوي على ثلاث قيم بالضبط.
يشير المثال التالي إلى أنّ
يجب أن تحتوي مصفوفة location
على عنصر واحد على الأقل:
Kotlin
fun getLocation(button: View, @Size(min=1) location: IntArray) { button.getLocationOnScreen(location) }
Java
void getLocation(View button, @Size(min=1) int[] location) { button.getLocationOnScreen(location); }
التعليقات التوضيحية للأذونات
استخدام @RequiresPermission
التعليق التوضيحي للتحقق من أذونات المتصل بطريقة ما. للتحقق من الحصول على إذن واحد
من قائمة الأذونات الصالحة، استخدِم السمة anyOf
. للتحقق من وجود مجموعة من
الأذونات، استخدِم السمة allOf
. يوضح المثال التالي
setWallpaper()
للإشارة إلى أن المتصل بالطريقة يجب أن لديه
إذن permission.SET_WALLPAPERS
:
Kotlin
@RequiresPermission(Manifest.permission.SET_WALLPAPER) @Throws(IOException::class) abstract fun setWallpaper(bitmap: Bitmap)
Java
@RequiresPermission(Manifest.permission.SET_WALLPAPER) public abstract void setWallpaper(Bitmap bitmap) throws IOException;
يتطلب المثال التالي المتصل بطريقة copyImageFile()
الحصول على إذن بالقراءة في وحدة التخزين الخارجية وإذن بالقراءة في الموقع
البيانات الوصفية في الصورة المنسوخة:
Kotlin
@RequiresPermission(allOf = [ Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.ACCESS_MEDIA_LOCATION ]) fun copyImageFile(dest: String, source: String) { ... }
Java
@RequiresPermission(allOf = { Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.ACCESS_MEDIA_LOCATION}) public static final void copyImageFile(String dest, String source) { //... }
بالنسبة إلى الأذونات في عناصر intent، ضع متطلبات الإذن في حقل السلسلة الذي يُحدِّد اسم الإجراء المطلوب:
Kotlin
@RequiresPermission(android.Manifest.permission.BLUETOOTH) const val ACTION_REQUEST_DISCOVERABLE = "android.bluetooth.adapter.action.REQUEST_DISCOVERABLE"
Java
@RequiresPermission(android.Manifest.permission.BLUETOOTH) public static final String ACTION_REQUEST_DISCOVERABLE = "android.bluetooth.adapter.action.REQUEST_DISCOVERABLE";
للأذونات على موفّري المحتوى الذين يحتاجون إلى أذونات منفصلة للقراءة والكتابة
إمكانية الوصول، يجب التفاف كل متطلبات الإذن في @RequiresPermission.Read
أو @RequiresPermission.Write
التعليق التوضيحي:
Kotlin
@RequiresPermission.Read(RequiresPermission(READ_HISTORY_BOOKMARKS)) @RequiresPermission.Write(RequiresPermission(WRITE_HISTORY_BOOKMARKS)) val BOOKMARKS_URI = Uri.parse("content://browser/bookmarks")
Java
@RequiresPermission.Read(@RequiresPermission(READ_HISTORY_BOOKMARKS)) @RequiresPermission.Write(@RequiresPermission(WRITE_HISTORY_BOOKMARKS)) public static final Uri BOOKMARKS_URI = Uri.parse("content://browser/bookmarks");
الأذونات غير المباشرة
عندما يعتمد أحد الأذونات على القيمة المحددة التي يتم تقديمها إلى معلمة الطريقة، استخدم
@RequiresPermission
في المعلَمة نفسها بدون إدراج الأذونات المحدّدة.
على سبيل المثال، startActivity(Intent)
إذنًا غير مباشر للغرض الذي تم تمريره إلى الطريقة:
Kotlin
abstract fun startActivity(@RequiresPermission intent: Intent, bundle: Bundle?)
Java
public abstract void startActivity(@RequiresPermission Intent intent, @Nullable Bundle)
عند استخدام أذونات غير مباشرة، تُجري أدوات الإصدار تحليلاً لتدفق البيانات للتحقق مما إذا كان
تحتوي الوسيطة التي تم تمريرها إلى الطريقة على أي تعليقات @RequiresPermission
توضيحية. ثم
فرض أي تعليقات توضيحية موجودة من المعلمة على الطريقة نفسها. في جلسة المعمل،
مثال startActivity(Intent)
، تتسبب التعليقات التوضيحية في الفئة Intent
في ظهور التحذيرات الناتجة
حول الاستخدامات غير الصالحة لـ startActivity(Intent)
عند نية الشراء بدون
يتم تمرير الأذونات إلى الطريقة، كما هو موضح في الشكل 1.
تنشئ أدوات التصميم التحذير على startActivity(Intent)
من التعليق التوضيحي.
في اسم إجراء intent المقابل في فئة Intent
:
Kotlin
@RequiresPermission(Manifest.permission.CALL_PHONE) const val ACTION_CALL = "android.intent.action.CALL"
Java
@RequiresPermission(Manifest.permission.CALL_PHONE) public static final String ACTION_CALL = "android.intent.action.CALL";
إذا لزم الأمر، يمكنك استبدال @RequiresPermission
بـ
@RequiresPermission.Read
أو @RequiresPermission.Write
عند إضافة تعليقات توضيحية
معلمة الطريقة. ومع ذلك، بالنسبة إلى الأذونات غير المباشرة، يجب على @RequiresPermission
لا يتم استخدامها مع التعليقات التوضيحية لأذونات القراءة أو الكتابة.
التعليقات التوضيحية للقيمة المعروضة
يمكنك استخدام التعليق التوضيحي @CheckResult
من أجل
التحقق من استخدام نتيجة الطريقة أو القيمة المعروضة بالفعل. بدلاً من إضافة تعليقات توضيحية إلى كل
طريقة غير باطلة مع @CheckResult
، أضِف التعليق التوضيحي لتوضيح نتائج
الطرق التي من المحتمل أن تكون مربكة.
على سبيل المثال، غالبًا ما يعتقد مطورو Java الجدد عن طريق الخطأ أن
تزيل الدالة <String>.trim()
المسافة البيضاء من السلسلة الأصلية. إضافة تعليقات توضيحية
تُستخدم الطريقة المتضمّنة @CheckResult
مَعلمة <String>.trim()
.
حيث لا يفعل المتصل أي شيء بالقيمة التي تعرضها الطريقة.
يوضّح المثال التالي السمة checkPermissions()
.
للتحقق مما إذا كانت القيمة المعروضة للطريقة
المشار إليها بالفعل. ويسمّى أيضًا enforcePermission()
كطريقة لاقتراحها على المطور كبديل:
Kotlin
@CheckResult(suggest = "#enforcePermission(String,int,int,String)") abstract fun checkPermission(permission: String, pid: Int, uid: Int): Int
Java
@CheckResult(suggest="#enforcePermission(String,int,int,String)") public abstract int checkPermission(@NonNull String permission, int pid, int uid);
تعليقات CallSuper التوضيحية
يمكنك استخدام التعليق التوضيحي @CallSuper
من أجل
التحقق من أن طريقة الإلغاء تستدعي التنفيذ المتميز للطريقة.
ما يلي:
يوضح هذا المثال الطريقة onCreate()
لضمان إلغاء أي طريقة
عمليات التنفيذ باستدعاء super.onCreate()
:
Kotlin
@CallSuper override fun onCreate(savedInstanceState: Bundle?) { }
Java
@CallSuper protected void onCreate(Bundle savedInstanceState) { }
التعليقات التوضيحية Typedef
تتحقق تعليقات Typedef مما إذا كانت هناك معلمة أو قيمة إرجاع أو حقل يشير إلى مجموعة معينة من الثوابت. كما أنها تتيح إكمال التعليمات البرمجية لتقديم الثوابت المسموح بها.
يمكنك استخدام @IntDef
و
@StringDef
تعليقات توضيحية لإنشاء تعليقات توضيحية العددية لمجموعات الأعداد الصحيحة والسلاسل للتحقق من صحة القيم
أنواع مراجع التعليمات البرمجية.
تستخدم التعليقات التوضيحية Typedef السمة @interface
للإشارة إلى النوع الجديد للتعليقات التوضيحية المعدودة.
التعليقان التوضيحيان @IntDef
و@StringDef
، بالإضافة إلى
@Retention
، وإضافة تعليقات توضيحية إلى التعليق التوضيحي الجديد، وتكون ضرورية لتحديد
نوع تعداد. يوضِّح التعليق التوضيحي @Retention(RetentionPolicy.SOURCE)
المجمِّع.
عدم تخزين بيانات التعليقات التوضيحية العددية في ملف .class
يعرض المثال التالي خطوات إنشاء تعليق توضيحي يتحقّق مما إذا كانت القيمة قد تم تمريرها. تشير معلمة الطريقة إلى أحد الثوابت المحددة:
Kotlin
import androidx.annotation.IntDef //... // Define the list of accepted constants and declare the NavigationMode annotation. @Retention(AnnotationRetention.SOURCE) @IntDef(NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS) annotation class NavigationMode // Declare the constants. const val NAVIGATION_MODE_STANDARD = 0 const val NAVIGATION_MODE_LIST = 1 const val NAVIGATION_MODE_TABS = 2 abstract class ActionBar { // Decorate the target methods with the annotation. // Attach the annotation. @get:NavigationMode @setparam:NavigationMode abstract var navigationMode: Int }
Java
import androidx.annotation.IntDef; //... public abstract class ActionBar { //... // Define the list of accepted constants and declare the NavigationMode annotation. @Retention(RetentionPolicy.SOURCE) @IntDef({NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS}) public @interface NavigationMode {} // Declare the constants. public static final int NAVIGATION_MODE_STANDARD = 0; public static final int NAVIGATION_MODE_LIST = 1; public static final int NAVIGATION_MODE_TABS = 2; // Decorate the target methods with the annotation. @NavigationMode public abstract int getNavigationMode(); // Attach the annotation. public abstract void setNavigationMode(@NavigationMode int mode); }
عند إنشاء هذا الرمز، يتم إنشاء تحذير إذا لم يتم إنشاء معلَمة mode
الإشارة إلى أحد الثوابت المحددة (NAVIGATION_MODE_STANDARD
،
NAVIGATION_MODE_LIST
أو NAVIGATION_MODE_TABS
).
يمكنك دمج @IntDef
و@IntRange
للإشارة إلى أنّ
يمكن أن يكون العدد الصحيح مجموعة معينة من الثوابت أو قيمة ضمن نطاق.
تفعيل دمج الثوابت باستخدام العلامات
إذا كان بإمكان المستخدمين دمج الثوابت المسموح بها مع علامة (مثل |
،
&
و^
وما إلى ذلك)، يمكنك تعريف تعليق توضيحي
flag
للتحقّق مما إذا كانت المَعلمة أو القيمة المعروضة تشير إلى نمط صالح.
ينشئ المثال التالي التعليق التوضيحي DisplayOptions
مع قائمة من القيم الصالحة
DISPLAY_
ثوابت:
Kotlin
import androidx.annotation.IntDef ... @IntDef(flag = true, value = [ DISPLAY_USE_LOGO, DISPLAY_SHOW_HOME, DISPLAY_HOME_AS_UP, DISPLAY_SHOW_TITLE, DISPLAY_SHOW_CUSTOM ]) @Retention(AnnotationRetention.SOURCE) annotation class DisplayOptions ...
Java
import androidx.annotation.IntDef; ... @IntDef(flag=true, value={ DISPLAY_USE_LOGO, DISPLAY_SHOW_HOME, DISPLAY_HOME_AS_UP, DISPLAY_SHOW_TITLE, DISPLAY_SHOW_CUSTOM }) @Retention(RetentionPolicy.SOURCE) public @interface DisplayOptions {} ...
عند إنشاء رمز برمجي يتضمّن علامة تعليق توضيحي، يتم إنشاء تحذير إذا كانت المَعلمة المزخرفة أو القيمة المعروضة لا تشير إلى نمط صالح.
الاحتفاظ بالتعليق التوضيحي
@Keep
أن التعليق التوضيحي يضمن عدم إزالة فئة أو طريقة بها تعليقات توضيحية عندما
يتم تصغيره في وقت التصميم. يكون هذا التعليق التوضيحي عادةً
مضافة إلى الطرق والفئات التي يتم الوصول إليها من خلال الانعكاس لمنع التجميع من
التعامل مع التعليمات البرمجية على أنها غير مستخدمة.
تنبيه: الصفوف والطرق التي تضيف تعليقات توضيحية إليها
التي تستخدم "@Keep
" دائمًا في حزمة APK لتطبيقك، حتى إذا لم
وتشير إلى هذه الفئات والأساليب ضمن منطق تطبيقك.
لإبقاء حجم التطبيق صغيرًا، يُرجى مراعاة ما إذا كان من الضروري الاحتفاظ
كل تعليق توضيحي من نوع @Keep
في تطبيقك. إذا كنت تستخدم الانعكاس
الوصول إلى فئة أو طريقة تتضمن تعليقات توضيحية، واستخدام
-if
شرطية في قواعد ProGuard، لتحديد الفئة
التي تجعل الانعكاس يستدعي.
لمزيد من المعلومات حول كيفية تصغير الرمز وتحديد الرمز الذي لا يجب إزالته، راجِع تقليص حجم تطبيقك وتشويشه وتحسينه.
التعليقات التوضيحية لمستوى ظهور الرمز
استخدم التعليقات التوضيحية التالية للإشارة إلى مستوى رؤية أجزاء معينة من الرمز، مثل الطرق أو الفئات أو الحقول أو الحزم.
إظهار الرمز للاختبار
تشير رسالة الأشكال البيانية
@VisibleForTesting
أن التعليق التوضيحي يظهر أكثر من اللازم عادةً لجعل
قابلة للاختبار. يحتوي هذا التعليق التوضيحي على وسيطة otherwise
اختيارية تتيح لك
تحديد مستوى رؤية الطريقة إذا لم يكن الأمر ضروريًا مما يجعلها مرئية
للاختبار. تستخدم أداة Lint الوسيطة otherwise
لفرض مستوى الرؤية المقصود.
في المثال التالي، تكون myMethod()
عادةً private
، ولكنها
package-private
للاختبارات. مع VisibleForTesting.PRIVATE
تعرض أداة Lint رسالة إذا تم استدعاء هذه الطريقة من خارج
السياق الذي يسمح به وصول private
، مثل من وحدة تجميع مختلفة.
Kotlin
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) fun myMethod() { ... }
Java
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) void myMethod() { ... }
يمكنك أيضًا تحديد @VisibleForTesting(otherwise = VisibleForTesting.NONE)
.
للإشارة إلى أن الطريقة موجودة فقط للاختبار. هذا النموذج مماثل لاستخدام
@RestrictTo(TESTS)
كلتاهما تقومان بإجراء نفس فحص الوبر.
حظر واجهة برمجة التطبيقات
@RestrictTo
يشير التعليق التوضيحي إلى أنّ الوصول إلى واجهة برمجة التطبيقات التي تتضمّن تعليقات توضيحية (الحزمة أو الفئة أو الطريقة) محدود،
على النحو التالي:
الفئات الفرعية
استخدِم نموذج التعليق التوضيحي @RestrictTo(RestrictTo.Scope.SUBCLASSES)
لتقييد
إمكانية وصول واجهة برمجة التطبيقات إلى الفئات الفرعية فقط.
ويمكن للفئات التي توسّع الفئة التي تتضمّن تعليقات توضيحية فقط الوصول إلى واجهة برمجة التطبيقات هذه. لغة Java
مفتاح التعديل protected
غير مقيّد بما يكفي لأنه يتيح الوصول
من الفئات غير المرتبطة ضمن نفس الحزمة. هناك أيضًا بعض الحالات التي تريد فيها مغادرة
public
لمزيد من المرونة في المستقبل، لأنه لا يمكنك أبدًا إنشاء
protected
والطريقة التي تم تجاوزها public
، ولكنك تريد تقديم
أن الفئة مخصصة للاستخدامات ضمن الفئة أو من الفئات الفرعية فقط.
المكتبات
استخدِم نموذج التعليق التوضيحي @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX)
من أجل
تقييد وصول واجهة برمجة التطبيقات إلى مكتباتك فقط.
ويمكن لرمز مكتبتك فقط الوصول إلى واجهة برمجة التطبيقات التي تتضمّن تعليقات توضيحية. لا يتيح لك هذا الأمر تنظيم التعليمة البرمجية فحسب
في أي تسلسل هرمي للحزمة الذي تريده ولكن أيضًا تشارك
التعليمة البرمجية بين مجموعة من المكتبات ذات الصلة. يتوفّر هذا الخيار حاليًا في Jetpack.
المكتبات التي تحتوي على الكثير من رموز التنفيذ غير المخصّصة للاستخدام الخارجي، والتي
يجب أن يكون public
لمشاركته عبر مكتبات Jetpack التكميلية المختلفة.
الاختبار
استخدِم نموذج التعليق التوضيحي @RestrictTo(RestrictTo.Scope.TESTS)
لمنع الآخرين
من الوصول إلى واجهات برمجة التطبيقات للاختبار.
يمكن للرمز البرمجي الاختباري فقط الوصول إلى واجهة برمجة التطبيقات التي تتضمّن تعليقات توضيحية. يمنع هذا الإجراء المطوّرين الآخرين من استخدام واجهات برمجة التطبيقات لأغراض التطوير التي تنوي استخدامها لأغراض الاختبار فقط.