Android Gradle Plugin 4.0.0 (אפריל 2020)

כדי להשתמש בגרסה הזו של הפלאגין ל-Android, נדרשים:

4.0.1 (יולי 2020)

העדכון המשני הזה תומך בתאימות להגדרות ברירת מחדל ולתכונות חדשות של חשיפה של חבילות ב-Android 11.

בגרסאות קודמות של Android, אפשר היה להציג רשימה של כל האפליקציות שמותקנות במכשיר. החל מ-Android 11 (רמת API 30), כברירת מחדל לאפליקציות יש גישה רק לרשימת חבילות מותקנות מסוננת. כדי לראות רשימה רחבה יותר של אפליקציות במערכת, עכשיו צריך להוסיף את הרכיב <queries> למניפסט Android של האפליקציה או הספרייה.

הפלאגין של Android Gradle מגרסה 4.1 ואילך כבר תואם להצהרה החדשה על <queries>, אבל גרסאות ישנות יותר לא תואמות. אם מוסיפים את האלמנט <queries> או מתחילים להסתמך על ספרייה או על SDK שתומכים בטירגוט ל-Android 11, יכול להיות שתבחינו בשגיאות במיזוג המניפסט בזמן ה-build של האפליקציה.

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

תמיכה ב-Android Studio Build Analyzer

החלון Build Analyzer עוזר לכם להבין ולזהות בעיות בתהליך ה-build, כמו אופטימיזציות מושבתות ומשימות שהוגדרו בצורה שגויה. התכונה הזו זמינה כשמשתמשים ב-Android Studio מגרסה 4.0 ואילך עם הפלאגין של Android Gradle מגרסה 4.0.0 ואילך. אפשר לפתוח את החלון Build Analyzer מ-Android Studio באופן הבא:

  1. אם עדיין לא עשיתם זאת, בוחרים באפשרות Build > Make Project בסרגל התפריטים כדי ליצור את האפליקציה.
  2. בסרגל התפריטים, בוחרים באפשרות View (תצוגה) > Tool Windows (חלונות כלים) > Build (פיתוח).
  3. בחלון Build, פותחים את החלון Build Analyzer באחת מהדרכים הבאות:
    • אחרי ש-Android Studio מסיים את ה-build של הפרויקט, לוחצים על הכרטיסייה Build Analyzer.
    • אחרי ש-Android Studio מסיים את ה-build של הפרויקט, לוחצים על הקישור בצד שמאל של החלון Build Output.

בחלון Build Analyzer, בעיות אפשריות ב-build מאורגנות בעץ בצד ימין. אפשר לבדוק כל בעיה ולחקור את הפרטים שלה בחלונית שמשמאל. כש-Android Studio מנתח את ה-build, הוא מחשב את הקבוצה של המשימות שקבעו את משך ה-build ומספק תצוגה חזותית כדי לעזור לכם להבין את ההשפעה של כל אחת מהמשימות האלה. אפשר גם לקבל פרטים על אזהרות על ידי הרחבת הצומת Warnings.

מידע נוסף זמין במאמר זיהוי נסיגה במהירות ה-build.

הסרת סוכר מספריות של Java 8 ב-D8 וב-R8

הפלאגין של Android Gradle כולל עכשיו תמיכה בשימוש במספר ממשקי API בשפת Java 8, בלי צורך ברמת API מינימלית באפליקציה.

באמצעות תהליך שנקרא desugaring, כבר בגרסה 3.0 ואילך של Android Studio, המהדר של DEX, D8, סיפק תמיכה משמעותית בתכונות השפה של Java 8 (כמו ביטויי lambda, שיטות ממשק ברירת מחדל, try with resources ועוד). ב-Android Studio 4.0, מנוע הסרת הסוכר הרחיב את היכולת שלו להסיר סוכר מממשקי API בשפת Java. המשמעות היא שאפשר עכשיו לכלול באפליקציות שתומכות בגרסאות ישנות יותר של Android ממשקי API רגילים של שפה, שהיו זמינים רק בגרסאות האחרונות של Android (כמו java.util.streams).

קבוצת ממשקי ה-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 החסרים, ומשלב אותו באפליקציה. תהליך הסרת הסוכר מכתיב מחדש את הקוד של האפליקציה כך שבזמן הריצה היא תשתמש בספרייה הזו במקום ב-API.

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

אפשרויות חדשות להפעלה או להשבתה של תכונות build

בגרסה 4.0.0 של הפלאגין של Android Gradle יש דרך חדשה לשלוט בתכונות ה-build שרוצים להפעיל ולהשבית, כמו View Binding ו-Data Binding. כשיתווספו תכונות חדשות, הן יושבתו כברירת מחדל. לאחר מכן תוכלו להשתמש בבלוק buildFeatures כדי להפעיל רק את התכונות הרצויות, וכך לבצע אופטימיזציה של ביצועי ה-build בפרויקט. אפשר להגדיר את האפשרויות לכל מודול בקובץ 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, כל מודולי התכונות יכלו להיות תלויים רק במודול הבסיסי של האפליקציה. כשמשתמשים בפלאגין של 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"))
    ...
}

בנוסף, צריך להפעיל את התכונה 'תלות בין תכונות' ב-Android Studio (כדי לתמוך בתכונה בזמן עריכת ההגדרות של Run, לדוגמה). לשם כך, לוחצים על Help (עזרה) > Edit Custom VM Options (עריכת אפשרויות VM בהתאמה אישית) בסרגל התפריטים, ומוסיפים את הפרטים הבאים:

-Drundebug.feature.on.feature=true

מטא-נתונים של יחסי תלות

כשאתם יוצרים את האפליקציה באמצעות הפלאגין של Android Gradle מגרסה 4.0.0 ואילך, הפלאגין כולל מטא-נתונים שמתארים את יחסי התלות שמקובצים באפליקציה. כשאתם מעלים את האפליקציה, מערכת Play Console בודקת את המטא-נתונים האלה כדי לספק לכם את היתרונות הבאים:

  • קבלת התראות על בעיות ידועות ב-SDK וביחסי התלות שבהם האפליקציה שלכם משתמשת
  • לקבל משוב שימושי לפתרון הבעיות האלה

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

הספריות מיוצאות בפורמט החבילה Prefab.

כל יחסי תלות יכול לחשוף חבילה אחת לכל היותר של Prefab, שמכילה מודול אחד או יותר. מודול Prefab הוא ספרייה אחת, שיכולה להיות ספרייה משותפת, ספרייה סטטית או ספרייה של כותרות בלבד.

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

הגדרת מערכת build מקומית חיצונית

כדי לראות את השלבים שצריך לבצע, פועלים לפי השלבים הבאים עבור מערכת ה-build הילידית החיצונית שבה אתם מתכוונים להשתמש.

כל אחד מיחסי התלות של ה-AAR באפליקציה שכולל קוד מקומי חושף קובץ Android.mk שצריך לייבא לפרויקט ndk-build. כדי לייבא את הקובץ הזה, משתמשים בפקודה import&endash;module, שמחפשת את הנתיבים שציינתם באמצעות המאפיין import&endash;add&endash;path בפרויקט ndk-build. לדוגמה, אם האפליקציה מגדירה את libapp.so ומשתמשת ב-curl, צריך לכלול את הקטע הבא בקובץ Android.mk:

  1. ל-CMake:

    add_library(app SHARED app.cpp)

    # Add these two lines. find_package(curl REQUIRED CONFIG) target_link_libraries(app curl::curl)

  2. עבור 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} ל-build של CMake, שמייבאים באמצעות הפקודה 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 הנוכחית מקשרת באופן אוטומטי את libapp.so ל-libcurl.so ומארזת את libcurl.so בקובץ ה-APK או בחבילת האפליקציות. למידע נוסף, אפשר לעיין בדוגמה ל-curl prefab{:.external}.

שינויים בהתנהגות

כשמשתמשים בגרסה הזו של הפלאגין, יכול להיות שתבחינו בשינויים הבאים בהתנהגות.

עדכוני הגדרות החתימה של v1/v2

ההתנהגות של הגדרות החתימה על האפליקציה בבלוק signingConfig השתנתה באופן הבא:

חתימה בגרסה 1

  • אם ההגדרה v1SigningEnabled מופעלת באופן מפורש, AGP מבצע חתימת אפליקציה בגרסה 1.
  • אם המשתמש משבית את v1SigningEnabled באופן מפורש, לא מתבצע חתימה על אפליקציות בגרסה 1.
  • אם המשתמש לא הפעיל באופן מפורש חתימה ב-v1, היא עשויה להיות מושבתת באופן אוטומטי על סמך minSdk ו-targetSdk.

חתימה ב-v2

  • אם ההגדרה v2SigningEnabled מופעלת באופן מפורש, AGP מבצע חתימת אפליקציה בגרסה 2.
  • אם המשתמש משבית את v2SigningEnabled באופן מפורש, לא מתבצע חתימה על אפליקציות v2.
  • אם המשתמש לא הפעיל במפורש חתימה ב-v2, היא עשויה להיות מושבתת באופן אוטומטי על סמך targetSdk.

השינויים האלה מאפשרים ל-AGP לבצע אופטימיזציה של גרסאות build על ידי השבתת מנגנון החתימה בהתאם לכך שהמשתמש הפעיל את הדגלים האלה באופן מפורש. לפני הגרסה הזו, יכול להיות שהאפשרות v1Signing תהיה מושבתת גם אם הפעלתם אותה במפורש, מה שעלול לבלבל.

הפלאגינים feature ו-instantapp של Android Gradle הוסרו

בגרסה 3.6.0 של הפלאגין של Android Gradle, הפלאגין של הפיצ'ר (com.android.feature) והפלאגין של האפליקציה ללא התקנה (com.android.instantapp) הוצאו משימוש, ובמקומם מומלץ להשתמש בפלאגין של התכונה הדינמית (com.android.dynamic-feature) כדי ליצור ולארז אפליקציות ללא התקנה באמצעות קובצי Android App Bundle.

ב-Android Gradle plugin מגרסה 4.0.0 ואילך, הפלאגינים האלה יצאו משימוש לגמרי. לכן, כדי להשתמש בפלאגין Android Gradle העדכני ביותר, צריך להעביר את האפליקציה ללא התקנה כך שתתמוך בקובצי Android App Bundle. העברת האפליקציות המיידיות תאפשר לכם ליהנות מהיתרונות של חבילות האפליקציות ולפשט את העיצוב המודולרי של האפליקציה.

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

הוסר תכונת עיבוד אנוטציות נפרדת

היכולת להפריד את עיבוד ההערות למשימה ייעודית הוסרה. האפשרות הזו שימשה לשמירה על הידור מצטבר של Java כשמשתמשים במעבדי הערות לא מצטברים בפרויקטים של Java בלבד. היא הופעלה על ידי הגדרת android.enableSeparateAnnotationProcessing ל-true בקובץ gradle.properties, והיא לא פועלת יותר.

במקום זאת, כדאי לעבור לשימוש במעבדי הערות מצטברות כדי לשפר את ביצועי ה-build.

includeCompileClasspath הוצא משימוש

הפלאגין של Android Gradle כבר לא מחפש מעבדי הערות שאתם מגדירים ב-classpath של הידור, ולא כולל אותם. בנוסף, לנכס ה-DSL‏ annotationProcessorOptions.includeCompileClasspath כבר אין השפעה. אם תכללו מעבדי הערות בנתיב ה-Classpath של הידור, ייתכן שתקבלו את השגיאה הבאה:

Error: Annotation processors must be explicitly declared now.

כדי לפתור את הבעיה, צריך לכלול מעבדי הערות בקובצי build.gradle באמצעות הגדרת התלות annotationProcessor. מידע נוסף זמין במאמר הוספת מעבדי הערות.

אריזה אוטומטית של יחסי תלות שנוצרו מראש ומשמשים את CMake

בגרסאות קודמות של Android Gradle Plugin, היה צריך לארוז באופן מפורש כל ספרייה מוכנה מראש שנעשה בה שימוש ב-build המקורי החיצוני של CMake באמצעות 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"))
  }
}

בגרסה 4.0 של הפלאגין של Android Gradle, ההגדרה שלמעלה כבר לא נדרשת, והיא תוביל לכישלון ה-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'

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

בעיות מוכרות

בקטע הזה מתוארות בעיות ידועות בפלאגין של Android Gradle בגרסה 4.0.0.

מרוץ תהליכים במנגנון העובדים של Gradle

שינויים בפלאגין Android Gradle 4.0 עלולים לגרום לתנאי מרוץ ב-Gradle כשמריצים אותו עם &endash;&endash;no&endash;daemon וגרסאות של Gradle 6.3 ואילך, וכתוצאה מכך גרסאות build נתקעות אחרי שהן מסתיימות.

הבעיה הזו תטופל ב-Gradle 6.4.