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

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

הוספת תלות של הפרויקט בספריות או בתוספים

הדרך הכי טובה להוסיף תלויות ב-build ולנהל אותן היא באמצעות קטלוגים של גרסאות, השיטה שבה משתמשים כברירת מחדל בפרויקטים חדשים. בקטע הזה מוסבר על סוגי ההגדרות הנפוצים ביותר שמשמשים לפרויקטים של Android. אפשרויות נוספות מפורטות בתיעוד של Gradle. דוגמה לאפליקציה שמשתמשת בקטלוגים של גרסאות מופיעה ב-Now in 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, ולאפשר לו לנהל את הגרסאות האלה בשבילכם. פרטים נוספים מופיעים במאמר בנושא שימוש ב-Bill of Materials.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

מידע נוסף על השימוש במעבדי הערות זמין במאמר בנושא הוספת מעבדי הערות.

lintChecks

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

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

lintPublish משתמשים בהגדרה הזו בפרויקטים של ספריות Android כדי לכלול בדיקות lint שרוצים ש-Gradle יקמפל לקובץ lint.jar ויארוז ב-AAR. כתוצאה מכך, גם בפרויקטים שמשתמשים ב-AAR שלכם יופעלו בדיקות ה-lint האלה. אם השתמשתם בעבר בהגדרת התלות lintChecks כדי לכלול בדיקות lint ב-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"))
}

Groovy

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 ספציפי

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

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

Kotlin

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

Groovy

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

עם זאת, אם רוצים להוסיף תלות בווריאנט שמשלב בין flavor של מוצר לבין סוג 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")
}

Groovy

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, מוצגות אזהרות של lint בקובץ קטלוג הגרסאות ובתיבת הדו-שיח Project Structure (מבנה הפרויקט) לגבי ערכות SDK ציבוריות ב-Google Play SDK Index, אם הבעיות הבאות רלוונטיות:

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

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

קובץ ה-build גם מכריז על תלות בפלאגין Android Gradle ‏(com.application.android). אם יש לכם כמה מודולים שמשתמשים באותו פלאגין, יכולה להיות רק גרסה אחת של הפלאגין בנתיב המחלקות של ה-build בכל המודולים. במקום לציין את הגרסה בכל אחד מסקריפטים של build של מודולים, צריך לכלול את יחסי התלות של הפלאגין בסקריפט ה-build של השורש עם הגרסה, ולציין שלא להחיל אותו. הוספת apply false אומרת ל-Gradle לציין את גרסת הפלאגין אבל לא להשתמש בה ב-build הבסיסי. בדרך כלל סקריפט הבנייה של השורש ריק, למעט הבלוק 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'
}