הוספת תלויות build

מערכת ה-build של Gradle ב-Android Studio מאפשרת לכלול קבצים בינאריים חיצוניים או מודולים של ספרייה ב-build כיחסי תלות. יחסי התלות יכולים להיות ממוקמים במכונה שלכם או במאגר מרוחק, וכל יחסי תלות מעבריים שהם מצהירים עליהם נכללים באופן אוטומטי. בדף הזה נסביר איך להשתמש ביחסי תלות בפרויקט Android, כולל פרטים על התנהגות והגדרות ספציפיות שספציפיות לפלאגין של Android Gradle (AGP). למדריך מושגים מעמיק יותר של יחסי תלות ב-Gradle אפשר לעיין גם במדריך Gradle לניהול תלות, אבל חשוב לזכור שבפרויקט Android צריך להשתמש רק בהגדרות התלות שמוגדרות בדף הזה.

הוספת תלות בספרייה או בפלאגין

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

למידע נוסף על הוספה וניהול של יחסי תלות מקומיים (לא נפוצים), ראו יחסי תלות מקומיים.

בדוגמה הבאה, אנחנו מוסיפים לפרויקט תלות בקובץ בינארי מרוחק (ספריית Jetpack Macrobenchmark), תלות במודול של ספרייה מקומית (myLibrary) ותלות בפלאגין (פלאגין Android Gradle). אלה השלבים הכלליים להוספת יחסי התלות האלה לפרויקט:

  1. מוסיפים כינוי לגרסה הרצויה של התלות בקטע [versions] בקובץ של קטלוג הגרסאות, שנקרא libs.versions.toml (בספרייה gradle בתצוגה Project או בספרייה Gradle Scripts בתצוגה Android):

    [versions]
    agp = "8.3.0"
    androidx-macro-benchmark = "1.2.2"
    my-library = "1.4"
    
    [libraries]
    ...
    
    [plugins]
    ...
    

    כינויים יכולים לכלול מקפים או קווים תחתונים. כתובות האימייל החלופיות האלה יוצרות ערכים מקוננים שאפשר להפנות אליהם בסקריפטים של build. ההפניות מתחילות בשם הקטלוג, החלק libs ב-libs.versions.toml. כשמשתמשים בקטלוג של גרסאות בודדות, מומלץ להשאיר את ערך ברירת המחדל 'libs'.

  2. מוסיפים כינוי לתלות בקטעים [libraries] (לקבצים בינאריים מרוחקים או למודולים של ספריות מקומיות) או [plugins] (לתוספים) בקובץ libs.versions.toml.

    [versions]
    ...
    
    [libraries]
    androidx-benchmark-macro = { group = "androidx.benchmark", name = "benchmark-macro-junit4", version.ref = "androidx-macro-benchmark" }
    my-library = { group = "com.myapplication", name = "mylibrary", version.ref = "my-library" }
    
    [plugins]
    androidApplication = { id = "com.android.application", version.ref = "agp" }
    

    חלק מהספריות זמינות בגיליון מפרטים (BOM) שפורסם, שמקבץ משפחות של ספריות והגרסאות שלהן. אפשר לכלול BOM בקטלוג הגרסאות ובקובצי ה-build, ולאפשר לו לנהל את הגרסאות בשבילכם. פרטים נוספים זמינים במאמר שימוש ברשימת הרכיבים.

  3. מוסיפים הפניה לכינוי של התלות לסקריפט ה-build של המודולים שדורשים את התלות. צריך להמיר את הקווים התחתונים והמקפים של הכינוי לנקודות כשמפנימים אליו מסקריפט build. סקריפט ה-build שלנו ברמת המודול ייראה כך:

    Kotlin

    plugins {
      alias(libs.plugins.androidApplication)
    }
    
    dependencies {
      implementation(libs.androidx.benchmark.macro)
      implementation(libs.my.library)
    }

    Groovy

    plugins {
      alias 'libs.plugins.androidApplication'
    }
    
    dependencies {
      implementation libs.androidx.benchmark.macro
      implementation libs.my.library
    }

    הפניות ליישומי פלאגין כוללות את plugins אחרי שם הקטלוג, והפניות לגרסה כוללות את versions אחרי שם הקטלוג (הפניות לגרסה לא נפוצות. ראו תלות עם אותם מספרי גרסה לדוגמאות של הפניות לגרסה). הפניות לספריות לא כוללות את המאפיין libraries, לכן אי אפשר להשתמש ב-versions או ב-plugins בתחילת כינוי לספרייה.

הגדרת יחסי תלות

בתוך הבלוק dependencies, אפשר להצהיר על תלות בספרייה באמצעות אחת מהגדרות יחסי התלות השונות (למשל, implementation שהוצגה מוקדם יותר). כל הגדרת תלות מספקת ל-Gradle הוראות שונות לגבי השימוש בתלות. בטבלה הבאה מתוארות כל ההגדרות שאפשר להשתמש בהן לצורך יחסי תלות בפרויקט Android.

הגדרות אישיות התנהגות
implementation Gradle מוסיף את התלות לנתיב ה-classpath של הידור ומארז את התלות בפלט של ה-build. כשמגדירים במודול יחסי תלות מסוג implementation, מודעים ל-Gradle שאתם לא רוצים שהמודול ידלוף את יחסי התלות למודולים אחרים בזמן הידור. כלומר, התלות לא זמינה למודולים אחרים שתלויים במודול הנוכחי.

שימוש בהגדרת התלות הזו במקום ב-api יכול להוביל לשיפורים משמעותיים בזמן ה-build, כי הוא מקטין את מספר המודולים שמערכת ה-build צריכה לכתוב מחדש. לדוגמה, אם יחסי התלות של implementation משנים את ה-API, Gradle ידרוש קומפילציה מחדש רק של יחסי התלות האלה ושל המודולים שתלויים בהם ישירות. רוב המודולים של האפליקציות והבדיקות צריכים להשתמש בתצורה הזו.

api Gradle מוסיף את התלות לנתיב ה-classpath של הידור ולפלט של ה-build. כשמודול כולל תלות ב-api, הוא מיידע את Gradle שהמודול רוצה לייצא באופן זמני שתלויות במודולים אחרים, כדי שהוא יהיה זמין להם גם בזמן ריצה וגם בזמן הקומפילציה (compile).

חשוב להשתמש בהגדרות האלה בזהירות ורק עם יחסי תלות שצריך לייצא באופן זמני לצרכנים אחרים ב-upstream. אם יחסי התלות של api משנים את ממשק ה-API החיצוני שלהם, Gradle ידרוש קומפילציה מחדש של כל המודולים שיש להם גישה ליחסי התלות האלה בזמן הקומפילציה. אם יש מספר גדול של יחסי תלות מסוג api, זמן ה-build עשוי להתארך באופן משמעותי. אלא אם רוצים לחשוף את ה-API של יחסי התלות למודול נפרד, במודולים של הספריות צריך להשתמש במקום זאת ביחסי תלות מסוג implementation.

compileOnly Gradle מוסיף את התלות לנתיב ה-classpath של הידור בלבד (כלומר, הוא לא מתווסף לפלט ה-build). האפשרות הזו שימושית כשאתם יוצרים מודול ל-Android ואתם צריכים את התלות במהלך הידור, אבל היא לא חובה שתהיה קיימת בזמן הריצה. לדוגמה, אם תסתמכו על ספרייה שכוללת רק הערות בזמן הידור – לרוב משמשות ליצירת קוד אבל לעיתים קרובות הן לא כלולות בפלט ה-build – תוכלו לסמן את הספרייה הזו compileOnly.

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

הערה: אי אפשר להשתמש בהגדרה compileOnly עם יחסי תלות של Android Archive‏ (AAR).

runtimeOnly Gradle מוסיפה את התלות לפלט ה-build בלבד, לשימוש במהלך זמן הריצה. כלומר, הוא לא מתווסף לנתיב ה-Classpath של הידור. ב-Android משתמשים באפשרות הזו לעיתים רחוקות, אבל היא נמצאת בשימוש נפוץ באפליקציות שרת כדי לספק הטמעות של רישום ביומן. לדוגמה, בספרייה אפשר להשתמש ב-API לרישום ביומן שלא כולל הטמעה. צרכני הספרייה הזו יכולים להוסיף אותה כתלות ב-implementation ולכלול תלות של runtimeOnly בהטמעה בפועל של הרישום ביומן.
ksp
kapt
annotationProcessor

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

כדי להוסיף תלות כזו, צריך להוסיף אותה לנתיב ה-classpath של מעבד ההערות באמצעות ההגדרות ksp, kapt או annotationProcessor. השימוש בהגדרות האלה משפר את ביצועי ה-build על ידי הפרדה בין ה-classpath ההידור בין ה-classpath של מעבד ההערות. אם Gradle מוצא מעבדי הערות בנתיב ה-classpath של הידור, הוא משבית את הימנעות מהידור, שמשפיעה לרעה על זמן ה-build (ב-Gradle 5.0 ואילך, מעבדי הערות שנמצאים בנתיב ה-classpath של הידור מתעלמים).

פלאגין Android Gradle מניח שיחס תלות הוא מעבד הערות אם קובץ ה-JAR שלו מכיל את הקובץ הבא:

META-INF/services/javax.annotation.processing.Processor

אם הפלאגין מזהה מעבד הערות שנמצא במסלול ה-Classpath של הידור, הוא יוצר שגיאת build.

ksp הוא מעבד סמלים של Kotlin, ומופעל על ידי המהדר של Kotlin.

kapt ו-apt הם כלים נפרדים שמעבדים הערות לפני הפעלת מהדרים של Kotlin או Java.

כשאתם מחליטים באיזו הגדרה להשתמש, כדאי להביא בחשבון את הנקודות הבאות:

  • אם מעבד זמין כמעבד סמלים של Kotlin, אפשר להשתמש בו כיחס תלות ksp. במאמר מעבר מ-kapt ל-ksp מוסבר בהרחבה איך משתמשים במעבדי הסמלים של Kotlin.
  • אם המעבד לא זמין כמעבד סמלים של Kotlin:
    • אם הפרויקט כולל מקור Kotlin (אבל יכול גם לכלול מקור Java), משתמשים ב-kapt כדי לכלול אותו.
    • אם בפרויקט נעשה שימוש רק במקור Java, צריך להשתמש ב-annotationProcessor כדי לכלול אותו.

למידע נוסף על שימוש במעבדי הערות, תוכלו לקרוא את המאמר הוספת מעבדי הערות.

lintChecks

צריך להשתמש בהגדרה הזו כדי לכלול ספרייה שמכילה את בדיקות לאיתור שגיאות בקוד שרוצים ש-Gradle יבצע כשיוצרים פרויקט באפליקציה ל-Android.

חשוב לזכור ש-AARs שמכילים קובץ lint.jar מריצים באופן אוטומטי את הבדיקות שמוגדרות בקובץ lint.jar הזה. אין צורך להוסיף תלות lintChecks מפורשת. כך אפשר להגדיר ספריות ובדיקות לאיתור שגיאות בקוד שקשורות אליהם באותה תלות, ולוודא שהבדיקות יופעלו כשהצרכנים משתמשים בספרייה.

lintPublish אפשר להשתמש בהגדרה הזו בפרויקטים של ספריות Android כדי לכלול בדיקות של איתור שגיאות בקוד (lint) שרוצים ש-Gradle תעבד לקובץ lint.jar ותארוז ב-AAR. כתוצאה מכך, בפרויקטים שצורכים את ה-AAR שלכם, המערכת תחיל גם את בדיקות איתור השגיאות בקוד. אם השתמשתם בעבר בהגדרת התלות lintChecks כדי לכלול בדיקות איתור שגיאות בקוד ב-AAR שפורסם, תצטרכו להעביר את יחסי התלות האלה ולהשתמש במקום זאת בהגדרה lintPublish.

Kotlin

dependencies {
  // Executes lint checks from the ":checks" project at build time.
  lintChecks(project(":checks"))
  // Compiles lint checks from the ":checks-to-publish" into a
  // lint.jar file and publishes it to your Android library.
  lintPublish(project(":checks-to-publish"))
}

מגניב

dependencies {
  // Executes lint checks from the ':checks' project at build time.
  lintChecks project(':checks')
  // Compiles lint checks from the ':checks-to-publish' into a
  // lint.jar file and publishes it to your Android library.
  lintPublish project(':checks-to-publish')
}

הגדרת יחסי תלות לגרסה ספציפית של build

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

לדוגמה, כדי להוסיף יחסי תלות בינאריים מרוחקים רק למאפיין המוצר 'חינמי' באמצעות ההגדרה implementation, צריך להשתמש בקוד הבא:

Kotlin

dependencies {
    freeImplementation("com.google.firebase:firebase-ads:21.5.1")
}

Groovy

dependencies {
    freeImplementation 'com.google.firebase:firebase-ads:21.5.1'
}

עם זאת, אם רוצים להוסיף תלות בוריאציה שמשלבת טעם מוצר וסוג build, צריך לאתחל את שם ההגדרה:

Kotlin

// Initializes a placeholder for the freeDebugImplementation dependency configuration.
val freeDebugImplementation by configurations.creating

dependencies {
    freeDebugImplementation(project(":free-support"))
}

Groovy

configurations {
    // Initializes a placeholder for the freeDebugImplementation dependency configuration.
    freeDebugImplementation {}
}

dependencies {
    freeDebugImplementation project(":free-support")
}

כדי להוסיף יחסי תלות של implementation לבדיקות המקומיות ולבדיקות עם מכשירי המדידה, צריך להשתמש בקוד הבא:

Kotlin

dependencies {
    // Adds a remote binary dependency only for local tests.
    testImplementation("junit:junit:4.12")

    // Adds a remote binary dependency only for the instrumented test APK.
    androidTestImplementation("androidx.test.espresso:espresso-core:3.6.1")
}

מגניב

dependencies {
    // Adds a remote binary dependency only for local tests.
    testImplementation 'junit:junit:4.12'

    // Adds a remote binary dependency only for the instrumented test APK.
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1'
}

עם זאת, הגדרות מסוימות לא הגיוניות במצב הזה. לדוגמה, מאחר שמודולים אחרים לא יכולים להיות תלויים ב-androidTest, תופיע האזהרה הבאה אם משתמשים בהגדרה androidTestApi:

WARNING: Configuration 'androidTestApi' is obsolete and has been replaced with
'androidTestImplementation'.

סדר התלות

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

לדוגמה, אם הפרויקט שלכם מצהיר על הדברים הבאים:

  • תלות ב-LIB_A וב-LIB_B (בסדר הזה)
  • ו-LIB_A תלוי ב-LIB_C וב-LIB_D (בסדר הזה)
  • ו-LIB_B תלוי גם ב-LIB_C

לאחר מכן, סדר התלות הקבוע יהיה כך:

  1. LIB_A
  2. LIB_D
  3. LIB_B
  4. LIB_C

כך אפשר לוודא שגם LIB_A וגם LIB_B יוכלו לשנות את הערך של LIB_C, ו-LIB_D עדיין תהיה בעדיפות גבוהה יותר מ-LIB_B, כי העדיפות של LIB_A (שתלויה בו) גבוהה יותר מ-LIB_B.

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

מידע על יחסי תלות ב-Play Console

כשאתם מפתחים את האפליקציה, AGP כולל מטא-נתונים שמתארים את יחסי התלות בספריות שמקובצים באפליקציה. כשאתם מעלים את האפליקציה, מערכת Play Console בודקת את המטא-נתונים האלה כדי לספק התראות על בעיות ידועות ב-SDK וביחסי התלות שבהם האפליקציה משתמשת. במקרים מסוימים, המערכת מספקת משוב שאפשר ליישם כדי לפתור את הבעיות האלה.

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

android {
    dependenciesInfo {
        // Disables dependency metadata when building APKs.
        includeInApk = false
        // Disables dependency metadata when building Android App Bundles.
        includeInBundle = false
    }
}

למידע נוסף על המדיניות שלנו ועל בעיות אפשריות בקשר ליחסי התלות, עיינו בדף התמיכה שלנו בנושא שימוש בערכות SDK של צד שלישי באפליקציה.

מדדי SDK

ב-Android Studio מוצגות אזהרות על שגיאות בקוד בקובץ של קטלוג הגרסאות ובתיבת הדו-שיח Project Structure לגבי ערכות SDK ציבוריות בGoogle Play SDK Index במקרים הבאים:

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

האזהרות הן אותות לכך שעליכם לעדכן את יחסי התלות האלה, כי שימוש בגרסאות מיושנות עלול למנוע מכם לפרסם ב-Google Play Console בעתיד.

הוספת יחסי תלות ב-build ללא קטלוגים של גרסאות

מומלץ להשתמש בקטלוגים של גרסאות כדי להוסיף ולנהל יחסי תלות, אבל יכול להיות שלא תצטרכו אותם בפרויקטים פשוטים. דוגמה לקובץ build שלא משתמש בקטלוגים של גרסאות:

Kotlin

plugins {
    id("com.android.application")
}

android { ... }

dependencies {
    // Dependency on a remote binary
    implementation("com.example.android:app-magic:12.3")
    // Dependency on a local library module
    implementation(project(":mylibrary"))
}

Groovy

plugins {
    id 'com.android.application'
}

android { ... }

dependencies {
    // Dependency on a remote binary
    implementation 'com.example.android:app-magic:12.3'
    // Dependency on a local library module
    implementation project(':mylibrary')
}

קובץ ה-build הזה מצהיר על תלות בגרסה 12.3 של ספריית App-magic, בתוך קבוצת מרחב השמות 'com.example.android'. ההצהרה על יחסי התלות הבינאריים מרחוק היא קיצור דרך לביטוי הבא:

Kotlin

implementation(group = "com.example.android", name = "app-magic", version = "12.3")

Groovy

implementation group: 'com.example.android', name: 'app-magic', version: '12.3'

קובץ ה-build גם מצהיר על תלות במודול של ספריות Android בשם 'mylibrary'. השם הזה חייב להיות זהה לשם הספרייה שהוגדר עם include: בקובץ settings.gradle.kts. כשמפתחים את האפליקציה, מערכת ה-build להדרת את מודול הספרייה וחבילות את התוכן שעבר הידור שנוצר באפליקציה.

קובץ ה-build גם מצהיר על תלות בפלאגין של Android Gradle (com.application.android). אם יש לכם כמה מודולים שמשתמשים באותו פלאגין, אפשר להשתמש רק בגרסה אחת של הפלאגין ב-build classpath בכל המודולים. במקום לציין את הגרסה בכל אחד מהסקריפטים של בניית המודול, צריך לכלול את התלות של הפלאגין בסקריפט של גרסת ה-root של ה-build עם הגרסה, ולציין שלא להחיל אותה. הוספת apply false מורה ל-Gradle לתעד את גרסת הפלאגין, אבל לא להשתמש בו ב-build ברמה הבסיסית. בדרך כלל סקריפט ה-build ברמה הבסיסית (root) ריק, מלבד הבלוק plugins הזה.

Kotlin

plugins {
    id("org.jetbrains.kotlin.android") version "1.9.0" apply false
}

Groovy

plugins {
    id com.android.application version 8.3.0-rc02 apply false
}

אם יש לכם פרויקט עם מודול יחיד, תוכלו לציין את הגרסה באופן מפורש בסקריפט ה-build ברמת המודול ולהשאיר את סקריפט ה-build ברמת הפרויקט ריק:

Kotlin

plugins {
    id("com.android.application") version "8.3.0"
}

Groovy

plugins {
    id 'com.android.application' version '8.3.0-rc02'
}