כשמפעילים את האופטימיזציה של האפליקציה עם הגדרות ברירת המחדל, 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 לא יכול לראות את הקריאה לשיטה שמבוססת על מחרוזת דינמית, ולכן האופטימיזציות שלו עלולות לשבור את הקוד.
זו לא רשימה מלאה של תרחישים שבהם נדרשים כללי שמירה, אבל התרחישים האלה מכסים את רוב המקרים שבהם יכול להיות שתצטרכו כללי שמירה.
איך מוסיפים כללי שמירה לאפליקציה
צריך להוסיף את הכללים לקובץ proguard-rules.pro שנמצא בתיקיית השורש של מודול האפליקציה. יכול להיות שהקובץ כבר נמצא שם, אבל אם לא, צריך ליצור אותו. כדי להחיל את הכללים בקובץ, צריך להצהיר על הקובץ בקובץ build.gradle.kts (או build.gradle) ברמת המודול, כמו שמוצג בקוד הבא:
Kotlin
android { buildTypes { release { isMinifyEnabled = true isShrinkResources = true proguardFiles( // File with default rules provided by the Android Gradle Plugin getDefaultProguardFile("proguard-android-optimize.txt"), // File with your custom rules "proguard-rules.pro" ) // ... } } // ... }
Groovy
android { buildTypes { release { minifyEnabled true shrinkResources true proguardFiles( // File with default rules provided by the Android Gradle Plugin getDefaultProguardFile('proguard-android-optimize.txt'), // File with your custom rules. 'proguard-rules.pro' ) // ... } } // ... }
כברירת מחדל, קובץ ה-build כולל גם את הקובץ proguard-android-optimize.txt. הקובץ הזה כולל כללים שנדרשים לרוב פרויקטי Android, ולכן כדאי להשאיר אותו בקובץ ה-build. הקובץ הזה מבוסס על הקובץ proguard-common.txt וכולל תוכן שמשותף עם הקובץ הזה.
באפליקציות גדולות יותר, הקוד נמצא בדרך כלל בכמה מודולים של ספריות. במקרים כאלה, עדיף בדרך כלל להציב את כללי השמירה לצד הקוד שהם חלים עליו במודול הספציפי של הספרייה. ההבדל המהותי בין שמירת כללי השמירה בספריות הוא באופן ההצהרה על הכללים האלה בקובץ build.gradle.kts (או build.gradle) של מודול הספרייה. מידע נוסף זמין במאמר אופטימיזציה למפתחי ספריות.
הוספת כלל שמירה
כשמוסיפים כללי שמירה, אפשר לכלול גם אפשרויות גלובליות וגם להגדיר כללי שמירה משלכם.
הגדרות גלובליות: הגדרות גלובליות הן הנחיות כלליות שמשפיעות על האופן שבו R8 פועל בכל בסיס הקוד. מידע נוסף זמין במאמר בנושא אפשרויות גלובליות.
כללי שמירה: צריך לתכנן את כללי השמירה בקפידה כדי להגיע לאיזון הנכון בין אופטימיזציה מקסימלית של הקוד לבין מניעת שיבוש לא מכוון של האפליקציה. במאמר הוספת כללי שמירה מוסבר איך לכתוב כללי שמירה.
כללי שמירה ליוצרים של ספריות
אחרי שתקראו על ההגדרות הגלובליות והתחביר של כללי השמירה, תוכלו לעיין באופטימיזציה למפתחי ספריות לקבלת פרטים נוספים.