Android Gradle Plugin 4.0.0 (אפריל 2020)
הגרסה הזו של הפלאגין ל-Android דורשת את הדברים הבאים:
-
Gradle 6.1.1. מידע נוסף זמין בקטע בנושא עדכון Gradle.
-
SDK Build Tools 29.0.2 ואילך.
העדכון הקטן הזה תומך בתאימות להגדרות ברירת מחדל חדשות ולתכונות חדשות של חבילות ב-Android 11.
בגרסאות קודמות של Android, הייתה אפשרות לראות רשימה של כל האפליקציות שמותקנות במכשיר. החל מ-Android 11 (רמת API 30), כברירת מחדל לאפליקציות יש גישה רק לרשימה מסוננת של חבילות מותקנות.
כדי לראות רשימה רחבה יותר של אפליקציות במערכת, צריך עכשיו להוסיף רכיב <queries> למניפסט של Android באפליקציה או בספרייה.
Android Gradle plugin 4.1+ כבר תואם להצהרה החדשה <queries>, אבל גרסאות ישנות יותר לא תואמות. אם מוסיפים את האלמנט <queries> או אם מתחילים להסתמך על ספרייה או על SDK שתומכים בטירגוט ל-Android 11, יכול להיות שתיתקלו בשגיאות במיזוג המניפסט כשתיצרו את האפליקציה.
כדי לפתור את הבעיה הזו, אנחנו מפרסמים סדרה של תיקוני באגים ל-AGP 3.3 ומעלה. אם אתם משתמשים בגרסה ישנה יותר של AGP, אתם צריכים לשדרג לאחת מהגרסאות הבאות:
| גרסת המינימום | גרסת ברירת המחדל | פתקים | |
|---|---|---|---|
| Gradle | 6.1.1 | 6.1.1 | יש מידע נוסף במאמר בנושא עדכון Gradle. |
| SDK Build Tools | 29.0.2 | 29.0.2 | התקנה או הגדרה של SDK Build Tools. |
מידע נוסף על התכונה החדשה הזו זמין במאמר בנושא חשיפת חבילות ב-Android 11.
תכונות חדשות
הגרסה הזו של Android Gradle plugin כוללת את התכונות החדשות הבאות.
תמיכה בכלי Build Analyzer של Android Studio
בחלון Build Analyzer אפשר להבין ולאבחן בעיות בתהליך הבנייה, כמו אופטימיזציות מושבתות ומשימות שהוגדרו בצורה לא תקינה.
התכונה הזו זמינה כשמשתמשים ב-Android Studio מגרסה 4.0 ואילך עם
Android Gradle plugin 4.0.0 ומעלה. כדי לפתוח את החלון Build Analyzer מ-Android Studio:
- אם עדיין לא עשיתם זאת, צריך לבנות את האפליקציה. לשם כך, בסרגל התפריטים בוחרים באפשרות Build > Make Project.
- בסרגל התפריטים, בוחרים באפשרות תצוגה > חלונות כלים > בנייה.
- בחלון Build, פותחים את החלון Build Analyzer באחת מהדרכים הבאות:
- אחרי ש-Android Studio מסיים לבנות את הפרויקט, לוחצים על הכרטיסייה Build Analyzer (כלי ניתוח ה-build).
- אחרי ש-Android Studio מסיים לבנות את הפרויקט, לוחצים על הקישור בצד שמאל של החלון Build Output.
בחלון Build Analyzer, בעיות אפשריות ב-build מסודרות בעץ בצד ימין. אפשר לבדוק כל בעיה וללחוץ עליה כדי לראות את הפרטים שלה בחלונית שמשמאל. כש-Android Studio מנתח את ה-build, הוא מחשב את קבוצת המשימות שקבעו את משך ה-build ומציג אותן באופן חזותי כדי לעזור לכם להבין את ההשפעה של כל אחת מהמשימות האלה. אפשר גם להרחיב את הצומת Warnings כדי לראות פרטים על האזהרות.
מידע נוסף זמין במאמר זיהוי רגרסיות במהירות הבנייה.
הסרת סוכר בספריית Java 8 ב-D8 וב-R8
התוסף Android Gradle כולל עכשיו תמיכה בשימוש במספר ממשקי API של שפת Java 8, בלי לדרוש רמת API מינימלית לאפליקציה.
באמצעות תהליך שנקרא desugaring, מהדר ה-DEX, D8, ב-Android Studio מגרסה 3.0 ואילך כבר סיפק תמיכה משמעותית בתכונות של שפת Java 8 (כמו ביטויי lambda, שיטות ברירת מחדל של ממשק, try with resources ועוד). ב-Android Studio 4.0, מנוע ה-desugaring הורחב כדי לאפשר desugaring של ממשקי API בשפת Java. המשמעות היא שעכשיו אפשר לכלול ממשקי API סטנדרטיים של שפות שהיו זמינים רק בגרסאות האחרונות של Android (כמו java.util.streams) באפליקציות שתומכות בגרסאות ישנות יותר של Android.
הגרסה הזו תומכת בממשקי ה-API הבאים:
- צפיות רצופות (
java.util.stream) - קבוצת משנה של
java.time -
java.util.function - פריטים שנוספו לאחרונה אל
java.util.{Map,Collection,Comparator} - רכיבים אופציונליים (
java.util.Optional,java.util.OptionalIntו-java.util.OptionalDouble) וכמה מחלקות חדשות אחרות שימושיות עם ממשקי ה-API שלמעלה - כמה תוספות ל-
java.util.concurrent.atomic(שיטות חדשות ב-AtomicInteger,AtomicLongו-AtomicReference) -
ConcurrentHashMap(עם תיקוני באגים ל-Android 5.0)
כדי לתמוך בממשקי ה-API של השפות האלה, קומפיילר D8 יוצר קובץ DEX נפרד של ספרייה שמכיל הטמעה של ממשקי ה-API החסרים, וכולל אותו באפליקציה. תהליך ה-desugaring משכתב את הקוד של האפליקציה כדי להשתמש בספרייה הזו בזמן הריצה.
כדי להפעיל תמיכה בממשקי ה-API האלה לשפות, צריך לכלול את השורות הבאות בקובץ build.gradle של מודול האפליקציה:
android {
defaultConfig {
// Required when setting minSdkVersion to 20 or lower
multiDexEnabled true
}
compileOptions {
// Flag to enable support for the new language APIs
coreLibraryDesugaringEnabled true
// Sets Java compatibility to Java 8
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.4'
}
android {
defaultConfig {
// Required when setting minSdkVersion to 20 or lower
multiDexEnabled = true
}
compileOptions {
// Flag to enable support for the new language APIs
isCoreLibraryDesugaringEnabled = true
// Sets Java compatibility to Java 8
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
}
dependencies {
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:1.0.4")
}
הערה: יכול להיות שתצטרכו לכלול את קטע הקוד שלמעלה גם בקובץ build.gradle של מודול ספרייה אם
-
הבדיקות המכשירות של מודול הספרייה משתמשות בממשקי ה-API של השפה (באופן ישיר או דרך מודול הספרייה או יחסי התלות שלו). כך נוכל לספק את ממשקי ה-API החסרים לחבילת ה-APK של הבדיקה עם המכשור.
-
אתם רוצים להריץ lint במודול הספרייה בבידוד. הסיבה לכך היא כדי לעזור ל-lint לזהות שימושים תקינים בממשקי ה-API של השפה ולמנוע דיווח על אזהרות שגויות.
אפשרויות חדשות להפעלה או להשבתה של תכונות בנייה
פלאגין Android Gradle בגרסה 4.0.0 מציג דרך חדשה לשלוט בתכונות של הגדרות ה-build שרוצים להפעיל או להשבית, כמו View Binding ו-Data Binding. כשנוסיף תכונות חדשות, הן יהיו מושבתות כברירת מחדל. אחר כך אפשר להשתמש בבלוק buildFeatures כדי להפעיל רק את התכונות הרצויות, וכך לשפר את ביצועי הבנייה של הפרויקט. אפשר להגדיר את האפשרויות של כל מודול בקובץ build.gradle ברמת המודול, באופן הבא:
android {
// The default value for each feature is shown below. You can change the value to
// override the default behavior.
buildFeatures {
// Determines whether to generate a BuildConfig class.
buildConfig = true
// Determines whether to support View Binding.
// Note that the viewBinding.enabled property is now deprecated.
viewBinding = false
// Determines whether to support Data Binding.
// Note that the dataBinding.enabled property is now deprecated.
dataBinding = false
// Determines whether to generate binder classes for your AIDL files.
aidl = true
// Determines whether to support RenderScript.
renderScript = true
// Determines whether to support injecting custom variables into the module’s R class.
resValues = true
// Determines whether to support shader AOT compilation.
shaders = true
}
}android {
// The default value for each feature is shown below. You can change the value to
// override the default behavior.
buildFeatures {
// Determines whether to generate a BuildConfig class.
buildConfig = true
// Determines whether to support View Binding.
// Note that the viewBinding.enabled property is now deprecated.
viewBinding = false
// Determines whether to support Data Binding.
// Note that the dataBinding.enabled property is now deprecated.
dataBinding = false
// Determines whether to generate binder classes for your AIDL files.
aidl = true
// Determines whether to support RenderScript.
renderScript = true
// Determines whether to support injecting custom variables into the module’s R class.
resValues = true
// Determines whether to support shader AOT compilation.
shaders = true
}
}אפשר גם לציין את הגדרת ברירת המחדל של התכונות האלה בכל המודולים בפרויקט, על ידי הוספה של אחת או יותר מההגדרות הבאות לקובץ gradle.properties של הפרויקט, כמו שמוצג בהמשך. חשוב לזכור שאפשר עדיין להשתמש בחסימה buildFeatures בקובץ build.gradle ברמת המודול כדי לשנות את הגדרות ברירת המחדל האלה ברמת הפרויקט.
android.defaults.buildfeatures.buildconfig=true
android.defaults.buildfeatures.aidl=true
android.defaults.buildfeatures.renderscript=true
android.defaults.buildfeatures.resvalues=true
android.defaults.buildfeatures.shaders=trueתלות בין תכונות
בגרסאות קודמות של Android Gradle Plugin, כל מודולי התכונות
יכלו להיות תלויים רק במודול הבסיסי של האפליקציה. כשמשתמשים בפלאגין Android Gradle מגרסה 4.0.0, אפשר עכשיו לכלול מודול תכונה שתלוי במודול תכונה אחר. כלומר, תכונה :video יכולה להיות תלויה בתכונה :camera, שתלויה במודול הבסיס, כפי שמוצג באיור שלמטה.
מודול התכונות :video תלוי בתכונה :camera, שתלויה במודול הבסיס :app.
המשמעות היא שכאשר האפליקציה מבקשת להוריד מודול תכונות, היא מורידה גם מודולים אחרים שהיא תלויה בהם. אחרי שיוצרים מודולים של תכונות לאפליקציה, אפשר להצהיר על תלות בין תכונה לתכונה בקובץ build.gradle של המודול. לדוגמה, המודול :video מכריז על תלות ב-:camera באופן הבא:
// In the build.gradle file of the ':video' module.
dependencies {
// All feature modules must declare a dependency
// on the base module.
implementation project(':app')
// Declares that this module also depends on the 'camera'
// feature module.
implementation project(':camera')
...
}// In the build.gradle file of the ':video' module.
dependencies {
// All feature modules must declare a dependency
// on the base module.
implementation(project(":app"))
// Declares that this module also depends on the 'camera'
// feature module.
implementation(project(":camera"))
...
}בנוסף, צריך להפעיל את התכונה feature-on-feature dependency ב-Android Studio (כדי לתמוך בתכונה כשעורכים את הגדרת ההרצה, למשל). לשם כך, לוחצים על Help > Edit Custom VM Options (עזרה > עריכת אפשרויות מותאמות אישית של מכונה וירטואלית) מסרגל התפריטים ומוסיפים את האפשרויות הבאות:
-Drundebug.feature.on.feature=trueמטא-נתונים של יחסי תלות
כשמפתחים אפליקציה באמצעות פלאגין Android Gradle מגרסה 4.0.0 ואילך, הפלאגין כולל מטא-נתונים שמתארים את יחסי התלות שעוברים קומפילציה באפליקציה. כשמעלים את האפליקציה, מערכת Play Console בודקת את המטא-נתונים האלה כדי לספק לכם את היתרונות הבאים:
- קבלת התראות לגבי בעיות מוכרות בערכות SDK וביחסי תלות שבהם נעשה שימוש באפליקציה
- קבלת משוב מעשי לפתרון הבעיות
הנתונים דחוסים, מוצפנים באמצעות מפתח חתימה של Google Play ונשמרים בבלוק החתימה של אפליקציית הגרסה. עם זאת, אתם יכולים לבדוק את המטא-נתונים בעצמכם בקבצים המקומיים של בניית הביניים בספרייה הבאה: <project>/<module>/build/outputs/sdk-dependencies/release/sdkDependency.txt.
אם אתם לא רוצים לשתף את המידע הזה, אתם יכולים לבטל את ההסכמה על ידי הוספת השורה הבאה לקובץ build.gradle של המודול:
android {
dependenciesInfo {
// Disables dependency metadata when building APKs.
includeInApk = false
// Disables dependency metadata when building Android App Bundles.
includeInBundle = false
}
}android {
dependenciesInfo {
// Disables dependency metadata when building APKs.
includeInApk = false
// Disables dependency metadata when building Android App Bundles.
includeInBundle = false
}
}ייבוא ספריות מקוריות מהתלויות ב-AAR
עכשיו אפשר לייבא ספריות C/C++ מהתלויות של AAR באפליקציה. כשפועלים לפי שלבי ההגדרה שמתוארים בהמשך, Gradle הופך את הספריות המקוריות האלה לזמינות לשימוש עם מערכת חיצונית לבניית קוד מקורי, כמו CMake. שימו לב ש-Gradle רק מאפשר להשתמש בספריות האלה ב-build, אבל עדיין צריך להגדיר את סקריפטים ה-build כדי להשתמש בהן.
הספריות מיוצאות באמצעות פורמט החבילה Prefab.
כל תלות יכולה לחשוף חבילת Prefab אחת לכל היותר, שמורכבת ממודול אחד או יותר. מודול Prefab הוא ספרייה יחידה, שיכולה להיות ספרייה משותפת, סטטית או ספרייה שמכילה רק קובצי כותרת.
בדרך כלל, שם החבילה זהה לשם הארטיפקט של Maven ושם המודול זהה לשם הספרייה, אבל זה לא תמיד נכון. כדי לדעת מהם השם של החבילה ושל המודול בספריות, יכול להיות שתצטרכו לעיין במסמכי התיעוד של התלות.
הגדרת מערכת חיצונית מובנית לבנייה
כדי לראות את השלבים שצריך לבצע, פועלים לפי השלבים הבאים עבור מערכת ה-build החיצונית המקורית שמתכננים להשתמש בה.
כל יחסי התלות מסוג AAR של האפליקציה שכוללים קוד מקומי חושפים קובץ Android.mk שצריך לייבא לפרויקט ndk-build. מייבאים את הקובץ הזה באמצעות הפקודה import&endash;module, שמחפשת את הנתיבים שציינתם באמצעות המאפיין import&endash;add&endash;path בפרויקט ndk-build. לדוגמה, אם האפליקציה שלכם מגדירה את libapp.so והיא משתמשת ב-curl, צריך לכלול את השורה הבאה בקובץ Android.mk:
-
ב-CMake:
add_library(app SHARED app.cpp)# Add these two lines. find_package(curl REQUIRED CONFIG) target_link_libraries(app curl::curl)
-
ב-
ndk-build:include $(CLEAR_VARS) LOCAL_MODULE := libapp LOCAL_SRC_FILES := app.cpp # Link libcurl from the curl AAR. LOCAL_SHARED_LIBRARIES := curl include $(BUILD_SHARED_LIBRARY)# If you don't expect that your project will be built using versions of the NDK # older than r21, you can omit this block. ifneq ($(call ndk-major-at-least,21),true) $(call import-add-path,$(NDK_GRADLE_INJECTED_IMPORT_PATH)) endif
# Import all modules that are included in the curl AAR. $(call import-module,prefab/curl)
יחסי תלות מקוריים שכלולים ב-AAR נחשפים לפרויקט CMake באמצעות המשתנה CMAKE_FIND_ROOT_PATH{: .external}. הערך הזה מוגדר באופן אוטומטי על ידי Gradle כשמפעילים את CMake, לכן אם מערכת ה-build שלכם משנה את המשתנה הזה, הקפידו להוסיף לו ערך ולא להקצות לו ערך.
כל תלות חושפת חבילת קובץ תצורה{: .external} ל-CMake build, שאותה מייבאים באמצעות הפקודה find_package{: .external}. הפקודה הזו מחפשת חבילות של קובצי הגדרות שתואמות לשם ולגרסה של החבילה שצוינו, ומציגה את היעדים שהיא מגדירה לשימוש ב-build. לדוגמה, אם האפליקציה מגדירה את libapp.so והיא משתמשת ב-curl, צריך לכלול את השורה הבאה בקובץ CMakeLists.txt:
add_library(app SHARED app.cpp)
# Add these two lines.
find_package(curl REQUIRED CONFIG)
target_link_libraries(app curl::curl)
עכשיו אפשר לציין את #include "curl/curl.h" ב-app.cpp. כשמבצעים build לפרויקט, מערכת ה-build החיצונית המקורית מקשרת אוטומטית את libapp.so
ל-libcurl.so ואורזת את libcurl.so ב-APK או ב-App Bundle. למידע נוסף, אפשר לעיין בדוגמה של curl prefab{:.external}.
שינויים בהתנהגות
כשמשתמשים בגרסה הזו של התוסף, יכול להיות שתיתקלו בשינויים הבאים בהתנהגות.
עדכוני הגדרות חתימה בגרסה 1 או בגרסה 2
ההתנהגות של הגדרות חתימה על אפליקציות בבלוק signingConfig השתנתה באופן הבא:
חתימה בגרסה 1
- אם
v1SigningEnabledמופעל באופן מפורש, AGP מבצע חתימת אפליקציה בגרסה 1. - אם המשתמש משבית באופן מפורש את
v1SigningEnabled, לא מתבצעת חתימה על אפליקציות בגרסה 1. - אם המשתמש לא הפעיל באופן מפורש חתימה בגרסה 1, אפשר להשבית אותה באופן אוטומטי על סמך
minSdkו-targetSdk.
חתימה בגרסה 2
- אם
v2SigningEnabledמופעל באופן מפורש, AGP מבצע חתימת אפליקציה בגרסה 2. - אם המשתמש משבית במפורש את
v2SigningEnabled, חתימת אפליקציות בגרסה 2 לא מתבצעת. - אם המשתמש לא הפעיל באופן מפורש את חתימה בגרסה 2, אפשר להשבית אותה באופן אוטומטי על סמך
targetSdk.
השינויים האלה מאפשרים ל-AGP לבצע אופטימיזציה של בניית האפליקציה על ידי השבתת מנגנון החתימה, בהתאם להגדרה המפורשת של הדגלים האלה על ידי המשתמש. לפני הגרסה הזו, יכול להיות ש-v1Signing הושבתה גם אם היא הופעלה באופן מפורש, וזה יכול היה להיות מבלבל.
הוסרו הפלאגינים feature ו-instantapp של Android Gradle
ב-Android Gradle Plugin 3.6.0 הוצא משימוש Feature plugin
(com.android.feature) ו-Instant App plugin
(com.android.instantapp) לטובת שימוש ב-Dynamic Feature plugin
(com.android.dynamic-feature) כדי לבנות ולדחוס את האפליקציות ללא התקנה באמצעות Android App Bundles.
ב-Android Gradle plugin מגרסה 4.0.0 ואילך, הפלאגינים האלה שהוצאו משימוש הוסרו לגמרי. לכן, כדי להשתמש בפלאגין Android Gradle העדכני, צריך להעביר את האפליקציה ללא התקנה כך שתתמוך ב-Android App Bundle. העברה של אפליקציות מיידיות מאפשרת לכם ליהנות מהיתרונות של חבילות App Bundle ולפשט את העיצוב המודולרי של האפליקציה.
הערה: כדי לפתוח פרויקטים שמשתמשים בפלאגינים שהוסרו ב-Android Studio מגרסה 4.0 ואילך, הפרויקט צריך להשתמש בפלאגין Android Gradle מגרסה 3.6.0 ומטה.
הוסרה התכונה 'עיבוד נפרד של הערות'
היכולת להפריד את עיבוד ההערות למשימה ייעודית הוסרה. האפשרות הזו שימשה לשמירה על קומפילציה מצטברת של Java כשמשתמשים במעבדי אנוטציות לא מצטברים בפרויקטים של Java בלבד. כדי להפעיל אותה, צריך להגדיר את android.enableSeparateAnnotationProcessing ל-true בקובץ gradle.properties, אבל זה כבר לא עובד.
במקום זאת, כדאי לעבור לשימוש במעבדי הערות מצטברים כדי לשפר את ביצועי הבנייה.
המאפיין includeCompileClasspath הוצא משימוש
הפלאגין Android Gradle לא בודק יותר מעבדי הערות ולא כולל אותם
שמצהירים עליהם בנתיב המחלקה של הקומפילציה, והמאפיין annotationProcessorOptions.includeCompileClasspath DSL כבר לא משפיע. אם כוללים מעבדי הערות בנתיב המחלקה של ההידור, יכול להיות שתופיע השגיאה הבאה:
Error: Annotation processors must be explicitly declared now.כדי לפתור את הבעיה, צריך לכלול מעבדי הערות בקובצי build.gradle באמצעות הגדרת התלות annotationProcessor.
מידע נוסף מופיע במאמר הוספת מעבדי הערות.
אריזה אוטומטית של תלויות מוכנות מראש שמשמשות את CMake
בגרסאות קודמות של Android Gradle Plugin, היה צריך לארוז באופן מפורש כל ספרייה מוכנה מראש שנעשה בה שימוש ב-CMake external native build באמצעות jniLibs. יכול להיות שיש ספריות בספרייה src/main/jniLibs של המודול, או אולי בספרייה אחרת שהוגדרה בקובץ build.gradle:
sourceSets {
main {
// The libs directory contains prebuilt libraries that are used by the
// app's library defined in CMakeLists.txt via an IMPORTED target.
jniLibs.srcDirs = ['libs']
}
}sourceSets {
main {
// The libs directory contains prebuilt libraries that are used by the
// app's library defined in CMakeLists.txt via an IMPORTED target.
jniLibs.setSrcDirs(listOf("libs"))
}
}ב-Android Gradle Plugin 4.0, ההגדרה שלמעלה כבר לא נחוצה ותגרום לכשל ב-build:
* What went wrong:
Execution failed for task ':app:mergeDebugNativeLibs'.
> A failure occurred while executing com.android.build.gradle.internal.tasks.Workers$ActionFacade
> More than one file was found with OS independent path 'lib/x86/libprebuilt.so'הגרסה החיצונית של בניית האפליקציה כוללת עכשיו אריזה אוטומטית של הספריות האלה, כך שאריזה מפורשת של הספריות באמצעות jniLibs יוצרת כפילות. כדי להימנע משגיאת ה-build, מעבירים את הספרייה שנבנתה מראש למיקום מחוץ ל-jniLibs או מסירים את ההגדרה jniLibs מהקובץ build.gradle.
בעיות מוכרות
בקטע הזה מתוארות בעיות מוכרות שקיימות בפלאגין Android Gradle גרסה 4.0.0.
מרוץ תהליכים במנגנון של Gradle worker
שינויים ב-Android Gradle Plugin 4.0 יכולים להפעיל מצב מירוץ ב-Gradle
כשמריצים עם &endash;&endash;no&endash;daemon וגרסאות של Gradle 6.3 ומטה, ולגרום
לביצועים של בנייה להיתקע אחרי שהבנייה מסתיימת.
הבעיה הזו תוקנה ב-Gradle 6.4.