כישורים ב-Android
הצגה ב-GitHubR8 Analyzer
android skills add --skill r8-analyzerכדי לספק את חוויית המשתמש הטובה ביותר, מומלץ לבצע אופטימיזציה של האפליקציה כדי שהיא תהיה קטנה ומהירה ככל האפשר. כלי האופטימיזציה של האפליקציה שלנו, שנקרא R8, מייעל את האפליקציה על ידי הסרת קוד ומשאבים שלא נמצאים בשימוש, כתיבה מחדש של קוד כדי לבצע אופטימיזציה של ביצועי זמן הריצה ועוד. למשתמשים שלכם, המשמעות היא:
- זמן הפעלה מהיר יותר
- שימוש מופחת בזיכרון
- שיפורים בביצועי העיבוד והזמן של הריצה
- פחות מקרי ANR
סקירה כללית על אופטימיזציה של R8
R8 משתמש בתהליך רב-שלבי כדי לבצע אופטימיזציה של האפליקציה מבחינת גודל ומהירות. בין הפעולות העיקריות:
כיווץ קוד (שנקרא גם tree shaking): R8 מזהה ומסיר קוד שלא ניתן להגיע אליו מהאפליקציה ומהתלות שלה בספריות. על ידי ניתוח נקודות הכניסה של האפליקציה (כמו
ActivitiesאוServicesשמוגדרות במניפסט), R8 יוצר גרף של קוד עם הפניות ומסיר כל מה שלא נשאר עם הפניות.אופטימיזציות לוגיות: R8 כותב מחדש את הקוד כדי לשפר את יעילות הביצוע ולהפחית את התקורה. בין הטכניקות העיקריות:
הוספת קוד של שיטה: R8 מחליף אתר של קריאה לשיטה בגוף בפועל של השיטה שנקראה. הפעולה הזו מבטלת את התקורה של קריאה לפונקציה ומאפשרת ל-R8 לבצע אופטימיזציות נוספות.
מיזוג כיתות: R8 משלב קבוצות של כיתות וממשקים לכיתה אחת. כך מצמצמים את מספר המחלקות באפליקציה, מפחיתים את העומס על הזיכרון ומשפרים את מהירות ההפעלה.
ערפול קוד (obfuscation) (שידוע גם כ"הקטנה"): כדי להקטין את הגודל של קובץ ה-DEX, R8 מקצר את השמות של המחלקות, השדות והמתודות (לדוגמה,
com.example.MyActivityיכול להפוך ל-a.b.a).
החל מגרסה 8.12.0 של פלאגין של Android Gradle (AGP), R8 גם מבצע אופטימיזציה של משאבים כחלק משלבי האופטימיזציה שלו. מידע נוסף זמין במאמר בנושא כיווץ מקורות המידע בצורה אופטימלית.
הפעלת אופטימיזציה
כדי להפעיל אופטימיזציה של אפליקציה, צריך להשתמש ב-DSL המתאים על סמך גרסת ה-AGP של הפרויקט. מומלץ להפעיל את האופטימיזציה של האפליקציה רק בגרסה הסופית של האפליקציה שאתם בודקים לפני הפרסום – בדרך כלל בגרסת ה-release – כי האופטימיזציות מגדילות את זמן ה-build של הפרויקט ויכולות להקשות על ניפוי הבאגים בגלל האופן שבו הן משנות את הקוד.
בגרסאות AGP 9.3 ואילך
כדי להפעיל את אופטימיזציית האפליקציה ב-AGP 9.3 ואילך:
- מגדירים את
enable = trueבבלוקoptimizationבסקריפט הבנייה ברמת האפליקציה של גרסת הייצור. - מוסיפים את כללי השמירה לקובץ עם הסיומת
.keepבערכת המקורsrc/<variant>/keepRules. לדוגמה,src/main/keepRules/custom-rules.keep.
Kotlin
android {
buildTypes {
release {
optimization {
enable = true // Enables code and resource optimizations.
}
}
}
}
מגניב
android {
buildTypes {
release {
optimization {
enable = true // Enables code and resource optimizations.
}
}
}
}
שפת DSL מדור קודם לגרסאות AGP ישנות יותר מ-9.3
כדי להפעיל אופטימיזציה של האפליקציה, מגדירים את isMinifyEnabled = true (לאופטימיזציה של קוד) ואת isShrinkResources = true (לאופטימיזציה של משאבים) בסקריפט ה-build ברמת האפליקציה של ה-build של הגרסה. מומלץ להפעיל תמיד את שתי ההגדרות.
DSL מדור קודם (Kotlin)
android {
buildTypes {
release {
// Enables code optimizations.
isMinifyEnabled = true
// Enables resource shrinking.
isShrinkResources = true
proguardFiles(
// Default file with automatically generated optimization rules.
getDefaultProguardFile("proguard-android-optimize.txt"),
...
)
...
}
}
...
}
DSL מדור קודם (Groovy)
android {
buildTypes {
release {
// Enables code optimizations.
minifyEnabled = true
// Enables resource shrinking.
shrinkResources = true
// Default file with automatically generated optimization rules.
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt')
...
}
}
}
שיפור האופטימיזציה של R8
היתרונות בביצועים של R8 קשורים ישירות לכמות בסיס הקוד שאפשר לבצע בו אופטימיזציה באמצעות R8. כדי להפיק את המרב מ-R8, מומלץ לפעול לפי השיטות המומלצות הבאות:
- הפעלת R8 במצב מלא
- הפעלה של ערפול קוד (obfuscation), אופטימיזציה וכיווץ
- הפעלת כיווץ מקורות מידע וכיווץ מקורות מידע שעבר אופטימיזציה
- משפרים את כללי השמירה כדי לאפשר אופטימיזציה מקסימלית של מחלקות, שדות ושיטות.
כדי לשפר את כללי השמירה, אפשר להשתמש בכלי לניתוח ההגדרות של R8.
כלי הניתוח של הגדרות R8 מאפשר לכם:
- כדי לעקוב אחרי האיכות הכוללת של הגדרות R8 ולשפר אותה, אפשר לעיין במדדים שמופיעים בדוח של כלי הניתוח של הגדרות R8.
- איך מוצאים את כללי השמירה הרחבים ביותר – אלה שמונעים את רוב האופטימיזציה
- ולהבין איזו אופטימיזציה הם מונעים, כדי לשפר אותם.
כלי הניתוח של הגדרות R8 זמין ב-AGP בגרסה 9.3.0-alpha05 או ב-R8 בגרסה 9.3.7-dev. מידע נוסף זמין במאמר בנושא ניתוח הגדרות R8.
אופטימיזציה של כיווץ מקורות המידע כדי ליצור אפליקציות קטנות עוד יותר
בגרסה 8.12.0 של AGP מוצגת תכונה של צמצום משאבים שעברה אופטימיזציה. המטרה היא לשלב אופטימיזציה של משאבים וקוד כדי ליצור אפליקציות קטנות ומהירות עוד יותר. לפני האופטימיזציה של צמצום המשאבים, כלי האריזה של נכסי Android (AAPT2) יצר כללי שמירה שטיפלו בצמצום המשאבים בנפרד מהקוד, ולעתים קרובות שמרו קוד או משאבים שלא הייתה אליהם גישה, או משאבים שהפנו אחד לשני.
בכיווץ משאבים שעבר אופטימיזציה, המשאבים נחשבים כחלק מקוד התוכנית, ויוצרים את תרשים ההפניה. אם לא מתבצעת הפניה לאוסף של קוד או משאבים, הוא לא מוגן על ידי כלל שמירה, ואפשר להסיר אותו.
הפעלה של כיווץ מקורות מידע שעבר אופטימיזציה
כדי להפעיל את צינור ה-**אופטימיזציה** החדש ל**כיווץ מקורות המידע** ב-AGP 8.12 או 8.13, מוסיפים את השורות הבאות לקובץ gradle.properties של ה**פרויקט**:
אם אתם משתמשים ב-AGP 9.0.0 או בגרסה חדשה יותר, אתם לא צריכים להגדיר את android.r8.optimizedResourceShrinking=true. כיווץ מקורות מידע שעבר אופטימיזציה מוחל באופן אוטומטי כשמפעילים את isShrinkResources = true בהגדרות של הגרסה.
אימות והגדרה של הגדרות האופטימיזציה של R8
כדי לאפשר ל-R8 להשתמש ביכולות האופטימיזציה המלאות שלו, צריך להסיר את השורה הבאה מקובץ gradle.properties של הפרויקט, אם היא קיימת:
bash android.enableR8.fullMode=false # Remove this line from your codebase.
שימו לב שהפעלת אופטימיזציה של האפליקציה מקשה על הבנת עקבות מחסנית, במיוחד אם R8 משנה את השמות של מחלקות או שיטות. כדי לקבל מעקב אחר מחסנית (stack trace) שתואם לקוד המקור, אפשר לעיין במאמר בנושא שחזור המעקב המקורי אחר המחסנית.
אם R8 מופעל, כדאי גם ליצור פרופילים להפעלה כדי לשפר עוד יותר את ביצועי ההפעלה.
אם הפעלתם אופטימיזציה של אפליקציות והיא גורמת לשגיאות, הנה כמה אסטרטגיות לפתרון הבעיות:
- הוספת כללי שמירה כדי להשאיר חלק מהקוד ללא שינוי.
- יישום הדרגתי של אופטימיזציות.
- צריך לעדכן את הקוד כדי להשתמש בספריות שמתאימות יותר לאופטימיזציה.
אם אתם רוצים לייעל את מהירות ה-build, במאמר הגדרת אופן ההפעלה של R8 מוסבר איך להגדיר את R8 בהתאם לסביבה שלכם.
שינויים בהתנהגות של גרסאות AGP ו-R8
בטבלה הבאה מפורטות התכונות העיקריות שהוצגו בגרסאות שונות של פלאגין של Android Gradle (AGP) ושל R8 compiler.
| גרסת AGP | תכונות חדשות |
|---|---|
| 9.3 |
שפת תצורה פשוטה יותר (DSL): בלוק חדש של `optimization {}` מאפשר להגדיר פחות הגדרות – כיווץ מקורות מידע שעבר אופטימיזציה תמיד מופעל, וכללי השמירה של Android הם ברירת מחדל שניתן לבטל.
`keepRules` קבוצת מקורות: If you use the new DSL, you must place your keep rules in the src/<variant>/keepRules קבוצת מקורות, in files with the suffix .keep. קבוצות המקורות תואמות גם ל-DSL מדור קודם.
כללים לשימוש ב-KMP (Kotlin MultiPlatform): ב-KMP אין יותר צורך להגדיר את publish = true, ויש תמיכה בקובץ המקור src/<variant>/keepRules עם התוסף .keep.
שימו לב: עדיין יש תמיכה ב-DSL מדור קודם. |
| 9.1 |
מחלקות שנארזות מחדש כברירת מחדל: R8 אורז מחדש מחלקות (מעביר אותן לחבילה ללא שם, ברמה העליונה) כדי לדחוס עוד יותר את קובץ ה-DEX, וכך אין צורך לציין את האפשרות -repackageclasses. מידע על אופן הפעולה של האפשרות הזו ועל אופן ההשבתה שלה זמין במאמר בנושא אפשרויות גלובליות.
|
| 9.0 |
כיווץ מקורות המידע עבר אופטימיזציה: מופעל כברירת מחדל (נשלט באמצעות android.r8.optimizedResourceShrinking). כיווץ מקורות המידע עבר אופטימיזציה עוזר לשלב כיווץ מקורות מידע עם צינור האופטימיזציה של הקוד, וכך ליצור אפליקציות קטנות ומהירות יותר. הכלי מבצע אופטימיזציה של הקוד ושל הפניות למשאבים בו-זמנית, וכך הוא מזהה משאבים שההפניה אליהם היא מקוד שלא נמצא בשימוש ומסיר אותם. זהו שיפור משמעותי לעומת תהליכי האופטימיזציה הנפרדים הקודמים.האפשרות הזו שימושית במיוחד לאפליקציות שמשתפות משאבים וקוד משמעותיים בין ענפים שונים של גורמי צורה, עם שיפורים שנמדדו של יותר מ-50% בגודל האפליקציה. הקטנת הגודל מאפשרת הורדות קטנות יותר, התקנות מהירות יותר וחוויית משתמש טובה יותר עם הפעלה מהירה יותר, עיבוד משופר ופחות שגיאות ANR. סינון כללים של ספריות: הוסרה התמיכה באפשרויות גלובליות (לדוגמה, -dontobfuscate) בכללי צרכן של ספריות, והאפליקציות יסננו אותן. מידע נוסף זמין במאמר בנושא הוספת אפשרויות גלובליות.בדיקות של ערכים ריקים (null) ב-Kotlin: אופטימיזציה מופעלת כברירת מחדל (נשלטת באמצעות -processkotlinnullchecks). בגרסה הזו בוצעו גם שיפורים משמעותיים במהירות ה-build. מידע נוסף זמין במאמר בנושא הגדרות גלובליות להוספת אופטימיזציה.אופטימיזציה של חבילות ספציפיות: אפשר להשתמש ב- packageScope כדי לבצע אופטימיזציה של חבילות ספציפיות. התמיכה הזו ניסיונית. מידע נוסף זמין במאמר בנושא אופטימיזציה של חבילות שצוינו באמצעות packageScope.אופטימיזציה כברירת מחדל: הפסקנו לתמוך ב- getDefaultProguardFile("proguard-android.txt") כי הוא כולל את -dontoptimize, ומומלץ להימנע ממנו. במקום זאת, צריך להשתמש ב-"proguard-android-optimize.txt". אם אתם צריכים להשבית את האופטימיזציה באפליקציה באופן גלובלי, צריך להוסיף את הדגל באופן ידני לקובץ Proguard.
|
| 8.12 |
אופטימיזציה של כיווץ משאבים: נוספה תמיכה ראשונית (נשלטת באמצעות android.r8.optimizedResourceShrinking). אופטימיזציה של כיווץ משאבים עוזרת לשלב כיווץ משאבים עם צינור האופטימיזציה של הקוד. צריך להפעיל אותה באופן ידני בגרסה הזו של AGP.Logcat retracing: Support for automatic retracing in the Android Studio Logcat window. |
| 8.6 |
שיפורים באיתור מקורות: כולל איתור מקורות של שם הקובץ ומספר השורה כברירת מחדל לכל הרמות של minSdk (בעבר נדרשה רמה של minSdk 26 ומעלה בגרסה 8.2).עדכון של R8 עוזר לוודא שקובצי מעקב אחר מחסנית (stack trace) מגרסאות obfuscated ניתנים לקריאה בקלות ובבירור. בגרסה הזו שיפרנו את המיפוי של מספרי השורות וקבצי המקור, כדי שיהיה קל יותר לכלים כמו Logcat ב-Android Studio לשחזר באופן אוטומטי קריסות לקוד המקור המקורי. |
| 8.0 |
מצב מלא כברירת מחדל: מצב מלא של R8 מספק אופטימיזציה חזקה משמעותית. ההגדרה הזו מופעלת כברירת מחדל. אפשר לבטל את ההצטרפות באמצעות android.enableR8.fullMode=false.
|
| 7.0 |
מצב מלא זמין: הושק כפיצ'ר אופציונלי באמצעות android.enableR8.fullMode=true. במצב מלא, המערכת מבצעת אופטימיזציות חזקות יותר על ידי הנחה של הנחות מחמירות יותר לגבי האופן שבו הקוד משתמש בהשתקפות ובתכונות דינמיות אחרות. השימוש ב-ProGuard מקטין את גודל האפליקציה ומשפר את הביצועים, אבל יכול להיות שיהיה צורך בכללי שמירה נוספים כדי למנוע את הסרת הקוד הנדרש.
|