بازرسی کد را با حاشیه نویسی بهبود بخشید

استفاده از ابزارهای بازرسی کد، مانند lint ، می‌تواند به شما در یافتن مشکلات و بهبود کدتان کمک کند، اما ابزارهای بازرسی فقط می‌توانند موارد زیادی را استنتاج کنند. به عنوان مثال، شناسه‌های منبع Android از یک int برای شناسایی رشته‌ها، گرافیک‌ها، رنگ‌ها و سایر انواع منابع استفاده می‌کنند، بنابراین ابزارهای بازرسی نمی‌توانند تشخیص دهند که چه زمانی یک منبع رشته را مشخص کرده‌اید که باید در آن رنگ مشخص می‌کردید. این وضعیت به این معنی است که برنامه شما ممکن است نادرست اجرا شود یا اصلا اجرا نشود، حتی اگر از بازرسی کد استفاده کنید.

حاشیه نویسی به شما امکان می دهد نکاتی را برای ابزارهای بازرسی کد مانند پرز ارائه کنید تا به شناسایی این مشکلات ظریف کد کمک کند. حاشیه نویسی ها به عنوان تگ های فراداده اضافه می شوند که به متغیرها، پارامترها، و مقادیر برگردانده می شوند تا مقادیر بازگشتی روش، پارامترهای ارسال شده، متغیرهای محلی و فیلدها را بررسی کنید. هنگامی که با ابزارهای بازرسی کد استفاده می شود، حاشیه نویسی می تواند به شما در تشخیص مشکلاتی مانند استثناهای اشاره گر تهی و تضاد نوع منبع کمک کند.

اندروید از طریق کتابخانه Jetpack Annotations از انواع حاشیه نویسی ها پشتیبانی می کند. از طریق بسته androidx.annotation می توانید به کتابخانه دسترسی داشته باشید.

توجه: اگر یک ماژول به یک پردازشگر حاشیه نویسی وابستگی دارد، باید از پیکربندی وابستگی kapt یا ksp برای Kotlin یا پیکربندی وابستگی annotationProcessor برای جاوا برای افزودن آن وابستگی استفاده کنید.

حاشیه نویسی را به پروژه خود اضافه کنید

برای فعال کردن حاشیه نویسی در پروژه خود، وابستگی androidx.annotation:annotation به کتابخانه یا برنامه خود اضافه کنید. هر حاشیه‌نویسی که اضافه می‌کنید، هنگام اجرای بازرسی کد یا کار lint بررسی می‌شود.

وابستگی کتابخانه Jetpack Annotations را اضافه کنید

کتابخانه Jetpack Annotations در Google's Maven Repository منتشر شده است. برای افزودن کتابخانه Jetpack Anotations به پروژه خود، خط زیر را در بلوک dependencies فایل build.gradle یا build.gradle.kts خود قرار دهید:

کاتلین

dependencies {
    implementation("androidx.annotation:annotation:1.8.1")
}

شیار

dependencies {
    implementation 'androidx.annotation:annotation:1.8.1'
}
سپس، در نوار ابزار یا اعلان همگام‌سازی که ظاهر می‌شود، روی همگام‌سازی اکنون کلیک کنید.

اگر از حاشیه نویسی در ماژول کتابخانه خود استفاده می کنید، حاشیه نویسی به عنوان بخشی از آرتیفکت آرشیو Android (AAR) با فرمت XML در فایل annotations.zip گنجانده می شود. افزودن وابستگی androidx.annotation برای هیچ یک از کاربران پایین دستی کتابخانه شما وابستگی ایجاد نمی کند.

توجه: اگر از دیگر کتابخانه‌های Jetpack استفاده می‌کنید، ممکن است نیازی به اضافه کردن وابستگی androidx.annotation نداشته باشید. از آنجا که بسیاری از کتابخانه های Jetpack دیگر به کتابخانه حاشیه نویسی وابسته هستند، ممکن است از قبل به حاشیه نویسی ها دسترسی داشته باشید.

برای فهرست کاملی از حاشیه‌نویسی‌های موجود در مخزن Jetpack، یا به مرجع کتابخانه Jetpack Annotations مراجعه کنید یا از ویژگی تکمیل خودکار برای نمایش گزینه‌های موجود برای import androidx.annotation. بیانیه.

بازرسی کد را اجرا کنید

برای شروع بازرسی کد از Android Studio، که شامل اعتبار سنجی حاشیه نویسی و بررسی خودکار پرزها می شود، از منو گزینه Analyze > Inspect Code را انتخاب کنید. Android Studio پیام‌های تضاد را نمایش می‌دهد تا مشکلات احتمالی را در مواردی که کد شما با حاشیه‌نویسی مغایرت دارد، پرچم‌گذاری کند و راه‌حل‌های ممکن را پیشنهاد کند.

همچنین می‌توانید با اجرای وظیفه lint با استفاده از خط فرمان ، حاشیه‌نویسی را اعمال کنید. اگرچه این ممکن است برای پرچم‌گذاری مشکلات با یک سرور یکپارچه‌سازی مداوم مفید باشد، اما وظیفه lint حاشیه‌نویسی بی‌ثبات را اعمال نمی‌کند (توضیح داده شده در بخش زیر). فقط اندروید استودیو این کار را انجام می دهد. برای کسب اطلاعات بیشتر در مورد فعال کردن و اجرای بازرسی پرز، به بهبود کد خود با بررسی لینت مراجعه کنید.

اگرچه تداخل حاشیه نویسی اخطار ایجاد می کند، اما این هشدارها مانع از کامپایل شدن برنامه شما نمی شود.

حاشیه نویسی پوچ

حاشیه نویسی پوچ می تواند در کد جاوا مفید باشد تا اینکه آیا مقادیر می توانند null باشند یا خیر. آنها در کد Kotlin کمتر مفید هستند، زیرا Kotlin قوانین پوچ پذیری را ایجاد کرده است که در زمان کامپایل اجرا می شوند.

حاشیه‌نویسی‌های @Nullable و @NonNull را برای بررسی پوچ بودن یک متغیر، پارامتر یا مقدار بازگشتی داده شده اضافه کنید. حاشیه نویسی @Nullable یک متغیر، پارامتر یا مقدار بازگشتی را نشان می دهد که می تواند null باشد. @NonNull یک متغیر، پارامتر یا مقدار بازگشتی را نشان می دهد که نمی تواند null باشد.

به عنوان مثال، اگر یک متغیر محلی که حاوی مقدار تهی است به عنوان پارامتر به یک متد با حاشیه نویسی @NonNull به آن پارامتر ارسال شود، ساخت کد یک هشدار ایجاد می کند که نشان دهنده یک تضاد غیر تهی است. همچنین، تلاش برای ارجاع به نتیجه روشی که توسط @Nullable مشخص شده است، بدون اینکه ابتدا بررسی کنید که آیا نتیجه صفر است یا خیر، یک هشدار تهی ایجاد می کند. فقط در صورتی از @Nullable در مقدار برگشتی یک متد استفاده کنید که هر استفاده از متد باید صریحاً تهی باشد.

مثال زیر پوچ بودن را در عمل نشان می دهد. کد مثال Kotlin از حاشیه نویسی @NonNull استفاده نمی کند زیرا زمانی که یک نوع غیر قابل تهی مشخص شود به طور خودکار به بایت کد تولید شده اضافه می شود. مثال جاوا از حاشیه نویسی @NonNull بر روی پارامترهای context و attrs استفاده می کند تا بررسی کند که مقادیر پارامترهای ارسال شده تهی نیستند. همچنین بررسی می‌کند که خود متد onCreateView() null را برنگرداند:

کاتلین

...
    /** Annotation not used because of the safe-call operator(?)**/
    override fun onCreateView(
            name: String?,
            context: Context,
            attrs: AttributeSet
    ): View? {
        ...
    }
...

جاوا

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 Studio از اجرای تجزیه و تحلیل پوچ پذیری برای استنباط خودکار و درج حاشیه نویسی پوچ در کد شما پشتیبانی می کند. تجزیه و تحلیل پوچ پذیری قراردادها را در سراسر سلسله مراتب روش در کد شما اسکن می کند تا تشخیص دهد:

  • فراخوانی متدهایی که می توانند null برگردانند.
  • روش هایی که نباید پوچ برگردانند.
  • متغیرهایی مانند فیلدها، متغیرهای محلی و پارامترها که می توانند تهی باشند.
  • متغیرهایی مانند فیلدها، متغیرهای محلی و پارامترهایی که نمی توانند مقدار تهی را نگه دارند.

سپس تجزیه و تحلیل به طور خودکار حاشیه نویسی تهی مناسب را در مکان های شناسایی شده درج می کند.

برای اجرای تجزیه و تحلیل پوچ پذیری در Android Studio، Analyze > Infer Nullity را انتخاب کنید. Android Studio حاشیه نویسی های Android @Nullable و @NonNull را در مکان های شناسایی شده در کد شما قرار می دهد. پس از اجرای تجزیه و تحلیل تهی، این یک تمرین خوب برای تأیید حاشیه نویسی تزریق شده است.

توجه: هنگام اضافه کردن حاشیه‌نویسی‌های پوچ، تکمیل خودکار ممکن است حاشیه‌نویسی IntelliJ @Nullable و @NotNull را به جای حاشیه‌نویسی پوچ Android پیشنهاد دهد و ممکن است کتابخانه مربوطه را به‌طور خودکار وارد کند. با این حال، جستجوگر پرز اندروید استودیو فقط به دنبال حاشیه‌نویسی‌های پوچ اندروید است. هنگام تأیید حاشیه‌نویسی‌های خود، تأیید کنید که پروژه شما از حاشیه‌نویسی‌های پوچ Android استفاده می‌کند تا بررسی‌کننده پرز بتواند به‌درستی در حین بازرسی کد به شما اطلاع دهد.

حاشیه نویسی منابع

اعتبارسنجی انواع منابع می تواند مفید باشد زیرا ارجاعات Android به منابع، مانند منابع قابل ترسیم و رشته ، به عنوان اعداد صحیح ارسال می شوند.

کدی که انتظار دارد یک پارامتر به نوع خاصی از منبع، مانند یک String ارجاع دهد، می تواند به نوع مرجع مورد انتظار int ارسال شود، اما در واقع به نوع دیگری از منبع، مانند منبع R.string اشاره می کند.

برای مثال، همانطور که در اینجا نشان داده شده است، حاشیه‌نویسی‌های @StringRes را اضافه کنید تا بررسی کنید که آیا یک پارامتر منبع دارای مرجع R.string است یا خیر:

کاتلین

abstract fun setTitle(@StringRes resId: Int)

جاوا

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 باشد:

کاتلین

fun setAlpha(@IntRange(from = 0, to = 255) alpha: Int) { ... }

جاوا

public void setAlpha(@IntRange(from=0,to=255) int alpha) { ... }

حاشیه نویسی @FloatRange بررسی می کند که آیا یک مقدار پارامتر شناور یا دوگانه در محدوده مشخصی از مقادیر ممیز شناور قرار دارد. مثال زیر نشان می دهد که پارامتر alpha باید دارای مقدار شناور از 0.0 تا 1.0 باشد:

کاتلین

fun setAlpha(@FloatRange(from = 0.0, to = 1.0) alpha: Float) {...}

جاوا

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 باید حداقل یک عنصر داشته باشد:

کاتلین

fun getLocation(button: View, @Size(min=1) location: IntArray) {
    button.getLocationOnScreen(location)
}

جاوا

void getLocation(View button, @Size(min=1) int[] location) {
    button.getLocationOnScreen(location);
}

حاشیه نویسی مجوز

از حاشیه نویسی @RequiresPermission برای تایید مجوزهای تماس گیرنده یک روش استفاده کنید. برای بررسی یک مجوز از لیست مجوزهای معتبر، از ویژگی anyOf استفاده کنید. برای بررسی مجموعه ای از مجوزها، از ویژگی allOf استفاده کنید. مثال زیر به متد setWallpaper() اشاره می کند تا نشان دهد که فراخوان متد باید permission.SET_WALLPAPERS را داشته باشد:

کاتلین

@RequiresPermission(Manifest.permission.SET_WALLPAPER)
@Throws(IOException::class)
abstract fun setWallpaper(bitmap: Bitmap)

جاوا

@RequiresPermission(Manifest.permission.SET_WALLPAPER)
public abstract void setWallpaper(Bitmap bitmap) throws IOException;

مثال زیر به تماس گیرنده متد copyImageFile() نیاز دارد که هم دسترسی خواندن به حافظه خارجی و هم دسترسی خواندن به ابرداده مکان در تصویر کپی شده داشته باشد:

کاتلین

@RequiresPermission(allOf = [
    Manifest.permission.READ_EXTERNAL_STORAGE,
    Manifest.permission.ACCESS_MEDIA_LOCATION
])
fun copyImageFile(dest: String, source: String) {
    ...
}

جاوا

@RequiresPermission(allOf = {
    Manifest.permission.READ_EXTERNAL_STORAGE,
    Manifest.permission.ACCESS_MEDIA_LOCATION})
public static final void copyImageFile(String dest, String source) {
    //...
}

برای مجوزهای intent، الزامات مجوز را در فیلد رشته ای که نام اقدام intent را تعریف می کند، قرار دهید:

کاتلین

@RequiresPermission(android.Manifest.permission.BLUETOOTH)
const val ACTION_REQUEST_DISCOVERABLE = "android.bluetooth.adapter.action.REQUEST_DISCOVERABLE"

جاوا

@RequiresPermission(android.Manifest.permission.BLUETOOTH)
public static final String ACTION_REQUEST_DISCOVERABLE =
            "android.bluetooth.adapter.action.REQUEST_DISCOVERABLE";

برای مجوزهای ارائه‌دهندگان محتوا که به مجوزهای جداگانه برای دسترسی خواندن و نوشتن نیاز دارند، هر مورد نیاز مجوز را در @RequiresPermission.Read یا @RequiresPermission.Write حاشیه‌نویسی بنویسید:

کاتلین

@RequiresPermission.Read(RequiresPermission(READ_HISTORY_BOOKMARKS))
@RequiresPermission.Write(RequiresPermission(WRITE_HISTORY_BOOKMARKS))
val BOOKMARKS_URI = Uri.parse("content://browser/bookmarks")

جاوا

@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) از یک مجوز غیرمستقیم در intent ارسال شده به متد استفاده می کند:

کاتلین

abstract fun startActivity(@RequiresPermission intent: Intent, bundle: Bundle?)

جاوا

public abstract void startActivity(@RequiresPermission Intent intent, @Nullable Bundle)

هنگامی که از مجوزهای غیرمستقیم استفاده می کنید، ابزارهای ساخت، تجزیه و تحلیل جریان داده را انجام می دهند تا بررسی کنند که آیا آرگومان ارسال شده به متد دارای حاشیه نویسی @RequiresPermission است یا خیر. سپس هر گونه حاشیه نویسی موجود را از پارامتر روی خود متد اعمال می کنند. در مثال startActivity(Intent) ، حاشیه‌نویسی‌ها در کلاس Intent هنگامی که یک intent بدون مجوزهای مناسب به متد ارسال می‌شود، هشدارهای ناشی از استفاده‌های نامعتبر از startActivity(Intent) را ایجاد می‌کنند، همانطور که در شکل 1 نشان داده شده است.

شکل 1. هشدار ایجاد شده از حاشیه نویسی مجوزهای غیرمستقیم در روش startActivity(Intent) .

ابزارهای ساخت اخطار را در startActivity(Intent) از حاشیه نویسی روی نام اقدام intent مربوطه در کلاس Intent ایجاد می کنند:

کاتلین

@RequiresPermission(Manifest.permission.CALL_PHONE)
const val ACTION_CALL = "android.intent.action.CALL"

جاوا

@RequiresPermission(Manifest.permission.CALL_PHONE)
public static final String ACTION_CALL = "android.intent.action.CALL";

در صورت لزوم، می‌توانید @RequiresPermission را برای @RequiresPermission.Read یا @RequiresPermission.Write در هنگام حاشیه‌نویسی پارامتر یک روش جایگزین کنید. با این حال، برای مجوزهای غیرمستقیم @RequiresPermission نباید همراه با یادداشت‌های مجوز خواندن یا نوشتن استفاده شود.

حاشیه نویسی ارزش بازگشتی

از حاشیه نویسی @CheckResult برای تأیید اینکه نتیجه یا مقدار برگشتی یک روش واقعاً استفاده شده است استفاده کنید. به جای حاشیه نویسی هر روش غیر خالی با @CheckResult ، حاشیه نویسی را اضافه کنید تا نتایج روش های بالقوه گیج کننده را روشن کنید.

به عنوان مثال، توسعه دهندگان جدید جاوا اغلب به اشتباه فکر می کنند که < String >.trim() فضای خالی را از رشته اصلی حذف می کند. حاشیه نویسی متد با پرچم های @CheckResult از < String >.trim() استفاده می کند که در آن تماس گیرنده با مقدار برگشتی متد کاری انجام نمی دهد.

مثال زیر متد checkPermissions() را برای بررسی اینکه آیا مقدار بازگشتی متد واقعاً ارجاع داده شده است یا خیر توضیح می دهد. همچنین متد enforcePermission() به عنوان روشی که باید به عنوان جایگزین به توسعه‌دهنده پیشنهاد شود نام می‌برد:

کاتلین

@CheckResult(suggest = "#enforcePermission(String,int,int,String)")
abstract fun checkPermission(permission: String, pid: Int, uid: Int): Int

جاوا

@CheckResult(suggest="#enforcePermission(String,int,int,String)")
public abstract int checkPermission(@NonNull String permission, int pid, int uid);

حاشیه نویسی CallSuper

از حاشیه نویسی @CallSuper استفاده کنید تا تأیید کنید که یک روش فراخوان اجرای فوق العاده متد را فراخوانی می کند.

مثال زیر متد onCreate() را حاشیه نویسی می کند تا اطمینان حاصل شود که هر پیاده سازی متد برتری super.onCreate() را فراخوانی می کند:

کاتلین

@CallSuper
override fun onCreate(savedInstanceState: Bundle?) {
}

جاوا

@CallSuper
protected void onCreate(Bundle savedInstanceState) {
}

حاشیه نویسی Typedef

حاشیه نویسی Typedef بررسی می کند که آیا یک پارامتر خاص، مقدار بازگشتی یا فیلد به مجموعه خاصی از ثابت ها ارجاع می دهد یا خیر. آنها همچنین تکمیل کد را برای ارائه خودکار ثابت های مجاز فعال می کنند.

از حاشیه نویسی @IntDef و @StringDef برای ایجاد حاشیه نویسی شمارش شده از مجموعه اعداد صحیح و رشته ها برای اعتبارسنجی انواع دیگر منابع کد استفاده کنید.

حاشیه نویسی Typedef از @interface برای اعلام نوع حاشیه نویسی شمارش شده جدید استفاده می کند. حاشیه نویسی @IntDef و @StringDef ، همراه با @Retention ، حاشیه نویسی جدید را نشان می دهد و برای تعریف نوع شمارش شده ضروری است. حاشیه نویسی @Retention(RetentionPolicy.SOURCE) به کامپایلر می گوید که داده های حاشیه نویسی شمارش شده را در فایل .class ذخیره نکند.

مثال زیر مراحل ایجاد حاشیه نویسی را نشان می دهد که بررسی می کند آیا مقداری که به عنوان پارامتر متد ارسال می شود به یکی از ثابت های تعریف شده ارجاع می دهد یا خیر:

کاتلین

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

}

جاوا

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_ ایجاد می کند:

کاتلین

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
...

جاوا

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 ، اگر این روش از خارج از زمینه مجاز توسط دسترسی private ، مانند یک واحد کامپایل متفاوت فراخوانی شود، lint پیامی را نمایش می دهد.

کاتلین

@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
fun myMethod() {
    ...
}

جاوا

@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
void myMethod() { ... }

همچنین می‌توانید @VisibleForTesting(otherwise = VisibleForTesting.NONE) را مشخص کنید تا نشان دهید که یک روش فقط برای آزمایش وجود دارد. این فرم مانند استفاده از @RestrictTo(TESTS) است. هر دو همان بررسی پرز را انجام می دهند.

یک API را محدود کنید

حاشیه نویسی @RestrictTo نشان می دهد که دسترسی به API مشروح (بسته، کلاس یا روش) محدود است، به شرح زیر:

زیر کلاس ها

از فرم حاشیه‌نویسی @RestrictTo(RestrictTo.Scope.SUBCLASSES) استفاده کنید تا دسترسی API را فقط به زیر کلاس‌ها محدود کنید.

فقط کلاس هایی که کلاس حاشیه نویسی را گسترش می دهند می توانند به این API دسترسی داشته باشند. اصلاح کننده protected جاوا به اندازه کافی محدود کننده نیست، زیرا امکان دسترسی از کلاس های نامرتبط در یک بسته را فراهم می کند. همچنین، مواردی وجود دارد که می‌خواهید یک متد را برای انعطاف‌پذیری آینده public بگذارید، زیرا هرگز نمی‌توانید یک متد protected و لغو شده قبلی را public کنید، اما می‌خواهید یک اشاره ارائه دهید که کلاس برای استفاده در کلاس یا از زیر کلاس‌ها در نظر گرفته شده است. فقط.

کتابخانه ها

از فرم حاشیه نویسی @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX) استفاده کنید تا دسترسی API را فقط به کتابخانه های خود محدود کنید.

فقط کد کتابخانه شما می تواند به API مشروح شده دسترسی داشته باشد. این به شما امکان می دهد نه تنها کد خود را در هر سلسله مراتب بسته ای که می خواهید سازماندهی کنید، بلکه کد را در میان گروهی از کتابخانه های مرتبط به اشتراک بگذارید. این گزینه در حال حاضر برای کتابخانه‌های Jetpack در دسترس است که کدهای پیاده‌سازی زیادی دارند که برای استفاده خارجی در نظر گرفته نشده است، اما باید public باشد تا آن را در کتابخانه‌های مختلف Jetpack مکمل به اشتراک بگذارد.

آزمایش کردن

از فرم حاشیه نویسی @RestrictTo(RestrictTo.Scope.TESTS) برای جلوگیری از دسترسی سایر توسعه دهندگان به APIهای آزمایشی شما استفاده کنید.

فقط کد آزمایشی می تواند به API مشروح شده دسترسی داشته باشد. این باعث می‌شود دیگر توسعه‌دهندگان نتوانند از APIهایی برای توسعه‌ای که فقط برای اهداف آزمایشی در نظر دارید استفاده کنند.