שיפור בדיקת הקוד בעזרת הערות

שימוש בכלים לבדיקת קוד, כמו lint, יכול לעזור לכם למצוא ולשפר את הקוד, אבל כלי בדיקה יכולים להסיק מסקנות בלבד. מזהי משאבים של Android, לדוגמה, להשתמש ב-int כדי לזהות מחרוזות, גרפיקה, צבעים וסוגי משאבים אחרים, כך שכלי הבדיקה לא יכולים לדעת אם ציינתם משאב מחרוזות שבו צריך ציינת צבע. במצב כזה ייתכן שהאפליקציה שלכם לא תפעל בצורה תקינה או לא תפעל כלל, גם אם משתמשים בבדיקת קוד.

הערות מאפשרות לספק רמזים לכלים לבדיקת קוד, כמו איתור שגיאות בקוד, כדי לזהות אותם לבעיות עם קוד עדין יותר. הערות מתווספות כתגי מטא נתונים שאתם מצרפים למשתנים, ומחזירה ערכים כדי לבדוק את השיטה שמחזירה ערכים, פרמטרים שהועברו, משתנים מקומיים ושדות. בשימוש עם כלים לבדיקת קוד, הערות יכולות לעזור לכם לגלות בעיות כמו חריגים מסוג null והתנגשויות בין סוגי משאבים.

מערכת Android תומכת במגוון הערות באמצעות ספריית ההערות של Jetpack. אפשר לגשת לספרייה דרך androidx.annotation חבילה.

הערה: אם המודול תלוי במעבד הערות, עליך להשתמש בהגדרת התלויות kapt או ksp עבור Kotlin או את תצורת התלות annotationProcessor של Java כדי להוסיף של יחסי התלות.

הוספת הערות לפרויקט

כדי להפעיל הערות בפרויקט, צריך להוסיף את androidx.annotation:annotation שתלויות בספרייה או באפליקציה שלכם. כל הערות שמוסיפים נבדקות כשמריצים קוד או משימה אחת (lint).

הוספת התלות של ספריית Jetpack הערות

ספריית ההערות ב-Jetpack פורסמה בתאריך מאגר Maven של Google. כדי להוסיף את ספריית ההערות ב-Jetpack לפרויקט, צריך לכלול את הפריטים הבאים שורה בבלוק dependencies של build.gradle או קובץ build.gradle.kts:

Kotlin

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

מגניב

dependencies {
    implementation 'androidx.annotation:annotation:1.8.1'
}
לאחר מכן, בסרגל הכלים או בהתראת הסנכרון שמופיעה, לוחצים על סנכרון עכשיו.

אם אתם משתמשים בהערות במודול הספרייה, הן נכללות פריט מידע שנוצר בתהליך הפיתוח (Artifact) מארכיון Android (AAR) בפורמט XML בקובץ annotations.zip. ההוספה של התלות ב-androidx.annotation לא יוצרת תלות של משתמשים במורד הזרם (downstream) של הספרייה.

הערה: אם אתם משתמשים בספריות אחרות של Jetpack, ייתכן שלא יהיה צורך להוסיף את התלות של androidx.annotation. כי הרבה אחרים ספריות Jetpack תלויות בספריית ההערות, ויכול להיות שכבר יש לכם גישה הערות.

לרשימה המלאה של ההערות שכלולות במאגר Jetpack, עיינו ב ספריית ההערות של Jetpack לעיין או להשתמש בתכונת ההשלמה האוטומטית כדי להציג את האפשרויות הזמינות דף חשבון import androidx.annotation..

הרצת בדיקות קוד

כדי להתחיל בדיקת קוד מ-Android Studio, שכוללת אימות של הערות בדיקה אוטומטית של איתור שגיאות בקוד, בוחרים באפשרות ניתוח > יש לבדוק את הקוד תפריט ב-Android Studio מוצגות הודעות התנגשות כדי לסמן בעיות אפשריות שבהן הקוד קונפליקט בהערות ומציע פתרונות אפשריים.

אפשר גם לאכוף הערות באמצעות המשימה lint באמצעות שורת הפקודה. למרות שזה יכול להיות שימושי לסימון בעיות בשרת אינטגרציה רציפה (CI), המשימה lint לא אוכפת null הערות (מתוארות בקטע הבא); הפעולה הזו מתבצעת רק ב-Android Studio. לקבלת מידע נוסף מידע על הפעלה והפעלה של שגיאות בקוד למידע נוסף, אפשר לעיין בקטע שיפור הקוד באמצעות איתור שגיאות בקוד (lint) .

למרות שיש התנגשויות בין הערות, הן יוצרות אזהרות, אבל האזהרות האלה לא מונעות את האפליקציה מההידור.

הערות לגבי איפוס

הערות איפוס יכולות להיות שימושיות בקוד Java כדי לאכוף אם ערכים יכולים להיות null. הם פחות שימושיים בקוד Kotlin, מכיוון ש-Kotlin יצר כללי יכולת ביטול שנאכפים זמן הידור.

הוספה של @Nullable וגם @NonNull הערות כדי לבדוק את ערכי ה-null של משתנה, פרמטר או ערך מוחזר מסוימים. @Nullable ההערה מציינת משתנה, פרמטר או ערך מוחזר שיכול להיות null. @NonNull מציין משתנה, פרמטר או ערך מוחזר שלא יכולים להיות null.

לדוגמה, אם משתנה מקומי שמכיל ערך null מועבר כפרמטר ל-method. עם ההערה @NonNull שמצורפת לפרמטר הזה, בניית הקוד יוצרת אזהרה שמציינת התנגשות שאינה אפסית. כמו כן, בניסיון להתייחס לתוצאה של שיטה שמסומנת על ידי @Nullable בלי לבדוק קודם אם התוצאה אפס יוצרת אזהרה של null. צריך להשתמש רק במאפיין @Nullable עם ערך ההחזרה של שיטה אם כל שימוש ב-method חייב להיות מסומן באופן מפורש כ-null.

הדוגמה הבאה ממחישה איך פונקציית ה-null פועלת. הקוד לדוגמה של Kotlin לא משתמש ההערה @NonNull מתווספת באופן אוטומטי לבייטקוד שנוצר כשמצוין סוג שהוא לא ערך null. בדוגמה של Java נעשה שימוש בהערה @NonNull בפרמטרים context ו-attrs כדי לבדוק שערכי הפרמטרים שהועברו שהם לא null. כמו כן, הוא בודק ששיטת onCreateView() עצמה לא מחזירה ערך null:

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 Studio יש תמיכה בביצוע ניתוח של יכולת אפס כדי להסיק באופן אוטומטי ולהוסיף לקוד הערות null. סריקה של ניתוח יכולת null את החוזים השונים בהיררכיות השיטות בקוד שלכם, כדי לזהות:

  • שיטות להתקשרות שיכולות להחזיר ערך null.
  • שיטות שלא אמורות להחזיר את הערך null.
  • משתנים כמו שדות, משתנים מקומיים ופרמטרים, שיכולים להיות null.
  • משתנים כמו שדות, משתנים מקומיים ופרמטרים, שלא ניתן מכיל ערך null.

לאחר מכן הניתוח מוסיף באופן אוטומטי את ההערות החסרות המתאימות את המיקומים שזוהו.

כדי להריץ ניתוח של יכולת null ב-Android Studio, בוחרים באפשרות ניתוח > הסקת ערכי אפס. מערכת Android Studio מוסיפה את ההערות @Nullable ו-@NonNull ב-Android ב- זוהו מיקומים בקוד שלך. אחרי שמריצים ניתוח null, מומלץ לאמת החדרת הערות.

הערה: כשמוסיפים הערות ליצירת ערך null, ההשלמה האוטומטית עשויה מציעים את IntelliJ @Nullable והקבוצה @NotNull הערות במקום הערות ה-null ב-Android ויכול לייבא באופן אוטומטי את הספרייה המתאימה. אבל הגרסה של Android Studio הכלי לבדיקת שגיאות בקוד מחפש רק הערות null ב-Android. במהלך האימות של בהערות, ודאו שהפרויקט שלכם משתמש בהערות ה-null ב-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 כדי לציין שהפרמטר חייב להיות מספר שלם של צבע. כלי ה-build יסמנו קוד שגוי מעביר מזהה משאב צבע כמו android.R.color.black, במקום מספר שלם של צבע, ל-methods עם הערות.

הערות לשרשורים

הערות לגבי שרשורים בוחנות אם קוראים לשיטה מסוג מסוים thread. השרשור הבא יש תמיכה בהערות:

כלי ה-build מתייחסים ל@MainThread ול @UiThread הערות ניתנות להחלפה, כך שניתן לקרוא ל-@UiThread מ-methods מ-@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 בודקת אם הוא פרמטר צף או פרמטר כפול נמצא בטווח שצוין של ערכי נקודה צפה (floating-point). הדוגמה הבאה מציינת הפרמטר alpha חייב להכיל ערך מסוג מספר ממשי (float) מ-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 הערה לאימות ההרשאות של מבצע הקריאה ב-method. כדי לבדוק אם יש הרשאה יחידה מרשימה של הרשאות חוקיות, צריך להשתמש במאפיין 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) {
    //...
}

להרשאות ב-Intents, מציבים את דרישת ההרשאה בשדה המחרוזת שמגדיר את שם פעולת 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) ה-method משתמשת בהרשאה עקיפה על הכוונה שמועברת ל-method:

Kotlin

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

Java

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

כשמשתמשים בהרשאות עקיפות, כלי ה-build מבצעים ניתוח של זרימת הנתונים כדי לבדוק אם לארגומנט שהועבר ל-method יש @RequiresPermission הערות כלשהן. לאחר מכן הם לאכוף הערות קיימות מהפרמטר על השיטה עצמה. ב דוגמה startActivity(Intent), הערות במחלקה Intent גורמות לאזהרות שיוצגו לגבי שימושים לא חוקיים ב-startActivity(Intent) כאשר כוונה ללא ההרשאות מועברות ל-method, כפי שמוצג באיור 1.

איור 1. האזהרה שנוצרה כתוצאה מעקיפה הערה על הרשאות בשיטת startActivity(Intent).

כלי ה-build יוצרים את האזהרה ב-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 כדי לוודא ש-method מחליף קוראת ליישום-העל של השיטה.

הבאים בדוגמה הזו מוסיפים הערות ל-method 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.

בדוגמה הבאה מוצגים השלבים ליצירת הערה שבודקת אם ערך עבר כפרמטר method מפנה לאחד מהקבועים המוגדרים:

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 ומבטיח שמחלקה או שיטה עם הערות לא יוסרו כאשר הקוד מוקטן בזמן ה-build. בדרך כלל, נוספו ל-methods ומחלקות שניגשים אליהן דרך הרהורים, כדי למנוע מהדר להתייחס לקוד כאילו הוא לא בשימוש.

זהירות: הכיתות והשיטות שמוסיפים הערות באמצעות @Keep יופיעו תמיד ב-APK של האפליקציה, גם אם אף פעם להפנות למחלקות ולשיטות האלה בלוגיקה של האפליקציה.

כדי שגודל האפליקציה יהיה קטן, כדאי לבדוק אם יש צורך בשימור כל הערה של @Keep באפליקציה. אם אתם משתמשים בהשתקפות לגשת לכיתה או לשיטה עם הערות, להשתמש -if מותנה בכללי ProGuard, ציון המחלקה שמבצעת את הקריאה של החשיבה מחדש.

לקבלת מידע נוסף על הקטנת הקוד וציון הקוד שאין להסיר, מידע נוסף זמין במאמר כיווץ, ערפול קוד (obfuscation) ואופטימיזציה של האפליקציה.

הערות של חשיפת קוד

בהערות הבאות אפשר לראות את הניראות של חלקים ספציפיים בקוד, כמו methods, מחלקות, שדות או חבילות.

הצגת הקוד לצורך בדיקה

@VisibleForTesting מציינת ששיטה עם הערות גלויה יותר מהרגיל כדי להפוך את שניתן לבדוק. להערה הזו יש ארגומנט otherwise אופציונלי שמאפשר להגדיר מה תהיה החשיפה של השיטה, אם לא יהיה צורך להציג אותה. לבדיקה. איתור השגיאות בקוד משתמש בארגומנט otherwise כדי לאכוף את החשיפה הרצויה.

בדוגמה הבאה, myMethod() הוא בדרך כלל private, אבל package-private לבדיקות. עם VisibleForTesting.PRIVATE סיווג, איתור שגיאות בקוד יציג הודעה אם מתבצעת קריאה לשיטה מחוץ הקשר שמותר על ידי הגישה של private, למשל מיחידת הידור אחרת.

Kotlin

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

Java

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

אפשר גם לציין @VisibleForTesting(otherwise = VisibleForTesting.NONE) כדי לציין ששיטה קיימת לצורך בדיקה בלבד. הטופס הזה זהה לשימוש @RestrictTo(TESTS) שתיהן מבצעות את אותה בדיקת שגיאות בקוד.

הגבלת API

@RestrictTo ההערה מציינת שהגישה ל-API עם הערות (package, מחלקה או method) מוגבלת, ככה:

מחלקות משנה

יש להשתמש בטופס ההערות @RestrictTo(RestrictTo.Scope.SUBCLASSES) כדי להגביל גישת API לכיתות משנה בלבד.

רק לכיתות שמרחיבים את המחלקה עם הערות יכולות לגשת ל-API הזה. ה-Java מגביל protected לא מגביל מספיק, כי הוא מאפשר גישה מכיתות לא קשורות באותה חבילה. בנוסף, יש מקרים שבהם תרצו להשאיר public לצורך גמישות עתידית, כי אף פעם לא ניתן ליצור protected ושינית את השיטה public, אבל ברצונך לספק לרמוז שהמחלקה מיועדת לשימושים בתוך הכיתה או במחלקות המשנה בלבד.

ספריות

להשתמש בטופס ההערות @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX) כדי להגביל את גישת ה-API לספריות בלבד.

רק קוד הספרייה יכול לגשת ל-API עם ההערות. כך תוכלו לא רק לארגן את הקוד בכל היררכיית חבילות שתרצו, וגם לשתף את הקוד בין קבוצה של ספריות קשורות. האפשרות הזו כבר זמינה ב-Jetpack שיש בהן הרבה קוד הטמעה שלא מיועד לשימוש חיצוני. הוא צריך להיות public כדי לשתף אותו בכל ספריות ה-Jetpack המשלימות.

בדיקה

יש להשתמש בטופס ההערות @RestrictTo(RestrictTo.Scope.TESTS) כדי למנוע לאפשר למפתחים לגשת לממשקי ה-API לבדיקה.

רק קוד הבדיקה יכול לגשת ל-API עם הערות. הפעולה הזו מונעת ממפתחים אחרים משימוש בממשקי API לצורכי פיתוח שמיועדים למטרות בדיקה בלבד.