מידע על כללי שמירה

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

תרחישים נפוצים שבהם נדרשים כללי שמירה

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

  • קוד שמתבצעת אליו גישה באמצעות רפלקציה: R8 לא יכול לזהות מתי מתבצעת גישה למחלקות, לשדות או למתודות באמצעות רפלקציה. לדוגמה, R8 לא יכול לזהות שיטה שנבדקה לפי השם שלה באמצעות Class.getDeclaredMethod() או הערה שאוחזרה באמצעות Class.getAnnotation(). במקרים כאלה, יכול להיות שהכלי R8 ישנה את השם של השיטות וההערות האלה או יסיר אותן לגמרי, מה שיוביל ל-ClassNotFoundException או ל-NoSuchMethodException בזמן הריצה.
  • קוד שנקרא מ-Java Native Interface‏ (JNI): כשקוד מקורי (C או C++) קורא לשיטת Java או Kotlin, או כשקוד Java או Kotlin קורא לקוד C++‎ באמצעות JNI, הקריאה מבוססת על חיפוש מחרוזת דינמי של שם השיטה. ‫R8 לא יכול לראות את הקריאה לשיטה שמבוססת על מחרוזת דינמית, ולכן האופטימיזציות שלו עלולות לשבור את הקוד.

הרשימה הזו לא ממצה את כל התרחישים שבהם נדרשים כללי שמירה, אבל היא כוללת את רוב המקרים שבהם יכול להיות שתצטרכו כללי שמירה.

איך מוסיפים כללי שמירה לאפליקציה

ההגדרה של כללי השמירה תלויה בגרסה של AGP שבה אתם משתמשים.

באפליקציות גדולות יותר, הקוד נמצא בדרך כלל בכמה מודולים של ספריות. במקרים כאלה, עדיף בדרך כלל להציב את כללי השמירה לצד הקוד שהם חלים עליו במודול הספציפי של הספרייה. ההבדל המהותי בין שמירת כללי השמירה בספריות הוא באופן ההצהרה על הכללים האלה בקובץ build.gradle.kts (או build.gradle) של מודול הספרייה. מידע נוסף זמין במאמר אופטימיזציה למפתחי ספריות.

בגרסאות AGP‏ 9.3 ואילך

מוסיפים את הכללים לקובץ עם הסיומת .keep בספרייה src/<variant>/keepRules. לדוגמה: src/main/keepRules/custom-rules.keep. שימו לב: שימוש ב-DSL המעודכן ל-AGP מגרסה 9.3 ואילך מאפשר גם אופטימיזציה של קוד וגם אופטימיזציה של משאבים, ולא מחייב אתכם להגדיר במפורש את קובץ ברירת המחדל של כללי השמירה ב-Android‏ (proguard-android-optimize.txt), כי הוא נכלל כברירת מחדל, אלא אם הוא מושמט במפורש.

Kotlin

android {
    buildTypes {
        release {
            optimization {
                enable = true // Enables code and resource optimizations.
            }
        }
    }
}

מגניב

android {
    buildTypes {
        release {
            optimization {
                enable = true // Enables code and resource optimizations.
            }
        }
    }
}

השמטה של כללי השמירה של פלטפורמת Android שמוגדרים כברירת מחדל (מתקדם)

‫AGP מספק קבוצה של כללי ברירת מחדל לפלטפורמת Android. כדי להשמיט את הכללים האלה מההגדרות של הפרויקט ולנהל את כל כללי השמירה בעצמכם, מגדירים את optimization.keepRules.includeDefault לערך false.

Kotlin

android {
    buildTypes {
        release {
            optimization {
                enable = true // Enables code and resource optimizations.
                keepRules {
                    includeDefault = false // The file with optimization
                    // rules for the Android platform is included by
                    // default. To omit this file, set this option to false.
                }
            }
        }
    }
}

מגניב

android {
    buildTypes {
        release {
            optimization {
                enable = true // Enables code and resource optimizations.
                keepRules {
                    includeDefault = false // The file with optimization
                    // rules for the Android platform is included by
                    // default. To omit this file, set this option to false.
                }
            }
        }
    }
}

שפת תצורה מדור קודם ל-AGP בגרסאות שקודמות ל-9.3

מוסיפים את הכללים לקובץ proguard-rules.pro שנמצא בתיקיית השורש של מודול האפליקציה. יכול להיות שהקובץ כבר נמצא שם, אבל אם לא, צריך ליצור אותו. כדי להחיל את הכללים בקובץ, צריך להצהיר על הקובץ בקובץ build.gradle.kts (או build.gradle) ברמת המודול.

כברירת מחדל, קובץ ה-build כולל גם את הקובץ proguard-android-optimize.txt. הקובץ הזה כולל כללים שנדרשים לרוב פרויקטי Android, ולכן כדאי להשאיר אותו בקובץ ה-build. הקובץ הזה מבוסס על הקובץ proguard-common.txt וכולל תוכן שמשותף עם הקובץ הזה.

‫DSL מדור קודם (Kotlin)

android {
    buildTypes {
        release {
            isMinifyEnabled = true
            isShrinkResources = true

            proguardFiles(
                // Default file with default optimization rules.
                getDefaultProguardFile("proguard-android-optimize.txt"),
                ...
            )
        }
    }
}

‫DSL מדור קודם (Groovy)

android {
    buildTypes {
        release {
            minifyEnabled = true
            shrinkResources = true

            // Default file with default optimization rules.
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt')
            ...
        }
    }
}

הוספת כלל שמירה

כשמוסיפים כללי שמירה, אפשר לכלול גם אפשרויות גלובליות וגם להגדיר כללי שמירה משלכם.

  • הגדרות גלובליות: הגדרות גלובליות הן הנחיות כלליות שמשפיעות על האופן שבו R8 פועל בכל בסיס הקוד. מידע נוסף זמין במאמר בנושא אפשרויות גלובליות.

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

כללי שמירה ליוצרי ספריות

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