העברת תצורת ה-build מ-Groovy ל-Kotlin

בפלאגין Android Gradle 4.0 נוספה תמיכה בשימוש ב-Kotlin בהגדרות ה-build של Gradle, כתחליף ל-Groovy, שפת התכנות שבה נהוג להשתמש בקובצי התצורה של Gradle.

מומלץ להשתמש ב-Kotlin במקום ב-Groovy לכתיבה של סקריפטים של Gradle, כי קל יותר לקרוא ב-Kotlin ויש בה בדיקה טובה יותר בזמן הידור ותמיכה טובה יותר ב-IDE.

למרות ש-Kotlin מציע כרגע שילוב טוב יותר בעורך הקוד של Android Studio בהשוואה ל-Groovy, גרסאות build ב-Kotlin בדרך כלל איטיות יותר מאשר ב-Groovy, ולכן כשאתם מחליטים אם לעבור, כדאי לשקול את הביצועים של גרסאות build.

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

ציר הזמן

החל מ-Android Studio Giraffe, פרויקטים חדשים משתמשים ב-Kotlin DSL (build.gradle.kts) כברירת מחדל להגדרת build. הכלים האלה מספקים חוויית עריכה טובה יותר בהשוואה ל-Groovy DSL (build.gradle) עם הדגשת תחביר, השלמת קוד וניווט להצהרות. למידע נוסף, קראו את המאמר Gradle Kotlin DSL Primer.

מונחים נפוצים

Kotlin DSL: מתייחס בעיקר ל-Kotlin DSL של פלאגין Android Gradle, או לפעמים ל-Kotlin DSL הבסיסי של Gradle.

במדריך הזה להעברת נתונים, אנחנו משתמשים במונחים 'Kotlin' ו-'Kotlin DSL' לסירוגין. בדומה לכך, משתמשים ב-Groovy וב-Groovy DSL לסירוגין.

מתן שמות לקובצי סקריפט

שמות הסיומת של קובצי הסקריפט מבוססים על השפה שבה נכתב קובץ ה-build:

  • קובצי build של Gradle שנכתבו ב-Groovy משתמשים בסיומת שם הקובץ .gradle.
  • בקובצי build של Gradle שנכתבו ב-Kotlin, אתם משתמשים בסיומת שם הקובץ .gradle.kts.

המרת התחביר

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

הוספת סוגריים לקריאות ל-method

'מגניב' מאפשר להשמיט סוגריים בקריאות שיטה, ואילו Kotlin דורשים אותם. כדי להעביר את ההגדרות, מוסיפים סוגריים לקריאות ה-method האלה. הקוד הזה מראה איך להגדיר הגדרה ב-Groovy:

compileSdkVersion 30

זהו אותו הקוד שכתוב ב-Kotlin:

compileSdkVersion(30)

הוספת = לשיחות של מטלות

ב-Groovy DSL אפשר להשמיט את אופרטור ההקצאה = כשמקצים מאפיינים, בעוד שב-Kotlin הוא נדרש. הקוד הזה מראה איך מקצים מאפיינים ב-Groovy:

java {
    sourceCompatibility JavaVersion.VERSION_17
    targetCompatibility JavaVersion.VERSION_17
}

הקוד הזה מראה איך להקצות מאפיינים ב-Kotlin:

java {
    sourceCompatibility = JavaVersion.VERSION_17
    targetCompatibility = JavaVersion.VERSION_17
}

המרת מחרוזות

אלה ההבדלים בין מחרוזות ב-Groovy לבין מחרוזות ב-Kotlin:

  • מירכאות כפולות למחרוזות: ב-Groovy אפשר להגדיר מחרוזות באמצעות גרשיים בודדים, אבל ב-Kotlin נדרש שימוש במירכאות כפולות.
  • הוספת מחרוזות לביטויים עם נקודות: ב-Groovy אפשר להשתמש רק בתחילית $ להוספת מחרוזות לביטויים עם נקודות, אבל ב-Kotlin צריך לעטוף את הביטויים עם נקודות בסוגריים מסולסלים. לדוגמה, ב-Groovy אפשר להשתמש ב-$project.rootDir, כפי שמתואר בקטע הקוד הבא:

        myRootDirectory = "$project.rootDir/tools/proguard-rules-debug.pro"
        

    אבל ב-Kotlin, הקוד הקודם קורא ל-toString() ב-project, ולא ב-project.rootDir. כדי לקבל את הערך של תיקיית השורש, צריך להקיף את הביטוי ${project.rootDir} בסוגריים מסולסלים:

        myRootDirectory = "${project.rootDir}/tools/proguard-rules-debug.pro"
        

    למידע נוסף, ראו תבניות מחרוזות במסמכי התיעוד של Kotlin.

שינוי השם של סיומות קבצים

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

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

מחליפים את def ב-val או ב-var

מחליפים את def ב-val או ב-var, שהם איך מגדירים משתנים ב-Kotlin. זוהי הצהרת משתנה ב-Groovy:

def building64Bit = false

זהו אותו קוד שנכתב ב-Kotlin:

val building64Bit = false

הוספת הקידומת is לנכסים בוליאניים

גרובי משתמש בלוגיקת ניכויים של נכסים על סמך שמות הנכסים. לנכס בוליאני foo, השיטות המוסקות יכולות להיות getFoo,‏ setFoo או isFoo. לכן, אחרי ההמרה ל-Kotlin, צריך לשנות את שמות המאפיינים לשיטות המופשטות שלא נתמכות ב-Kotlin. לדוגמה, כדי להשתמש באלמנטים בוליאנים של buildTypes DSL, צריך להוסיף להם את הקידומת is. הקוד הזה מראה איך להגדיר מאפיינים בוליאניים ב-Groovy:

android {
    buildTypes {
        release {
            minifyEnabled true
            shrinkResources true
            ...
        }
        debug {
            debuggable true
            ...
        }
    ...

הקוד הבא הוא אותו הקוד ב-Kotlin. שימו לב שהתחילית של המאפיינים היא is.

android {
    buildTypes {
        getByName("release") {
            isMinifyEnabled = true
            isShrinkResources = true
            ...
        }
        getByName("debug") {
            isDebuggable = true
            ...
        }
    ...

המרת רשימות ומפות

הרשימות והמפות ב-Groovy וב-Kotlin מוגדרות באמצעות תחביר שונה. מגניב משתמש ב-[], ו-Kotlin קורא לשיטות ליצירת איסוף מפורשות באמצעות listOf או mapOf. חשוב להחליף את [] ב-listOf או ב-mapOf במהלך ההעברה.

כך מגדירים רשימה ב-Groovy לעומת Kotlin:

jvmOptions += ["-Xms4000m", "-Xmx4000m", "-XX:+HeapDumpOnOutOfMemoryError</code>"]

זהו אותו קוד שנכתב ב-Kotlin:

jvmOptions += listOf("-Xms4000m", "-Xmx4000m", "-XX:+HeapDumpOnOutOfMemoryError")

כך מגדירים מפה ב-Groovy לעומת Kotlin:

def myMap = [key1: 'value1', key2: 'value2']

זהו אותו הקוד שכתוב ב-Kotlin:

val myMap = mapOf("key1" to "value1", "key2" to "value2")

הגדרה של סוגי גרסאות build

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

ב-Groovy אפשר להשתמש בסוגי build מסוימים, כמו debug,‏ release ועוד, בלי ליצור אותם קודם. קטע הקוד הבא מציג הגדרה עם סוגי ה-build debug,‏ release ו-benchmark ב-Groovy.

buildTypes {
 debug {
   ...
 }
 release {
   ...
 }
 benchmark {
   ...
 }
}

כדי ליצור את התצורה המקבילה ב-Kotlin, צריך ליצור באופן מפורש את סוג ה-build benchmark.

buildTypes {
 debug {
   ...
 }

 release {
   ...
 }
 register("benchmark") {
    ...
 }
}

מעבר מ-buildscript לבלוק של פלאגינים

אם ה-build שלכם משתמש בבלוק buildscript {} כדי להוסיף יישומי פלאגין לפרויקט, צריך לשנות את הקוד (Refactoring) כדי להשתמש בבלוק plugins {} במקום. בעזרת הבלוק plugins {} קל יותר להחיל יישומי פלאגין, והוא פועל היטב עם קטלוגים של גרסאות.

בנוסף, כשמשתמשים בבלוק plugins {} בקובצי ה-build, מערכת Android Studio מודעת להקשר גם כשה-build נכשל. ההקשר עוזר בתיקונים בקובצי Kotlin DSL, כי הוא מאפשר לסביבת הפיתוח המשולבת של Studio לבצע השלמת קוד ולספק הצעות מועילות נוספות.

איתור מזהי יישומי הפלאגין

בעוד שהבלוק buildscript {} מוסיף את הפלאגינים לנתיב ה-classpath של ה-build באמצעות הקואורדינטות של Maven של הפלאגין, למשל com.android.tools.build:gradle:7.4.0, בבלוק plugins {} נעשה שימוש במזהי הפלאגין במקום זאת.

ברוב יישומי הפלאגין מזהה הפלאגין הוא המחרוזת שבה מחילים אותם באמצעות apply plugin. לדוגמה, מזהי הפלאגין הבאים הם חלק מהפלאגין של Android Gradle:

  • com.android.application
  • com.android.library
  • com.android.lint
  • com.android.test

תוכלו למצוא את הרשימה המלאה של יישומי הפלאגין במאגר Google Maven.

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

מזהים מקוצרים של פלאגינים מזהי פלאגין במרחב שמות
kotlin org.jetbrains.kotlin.jvm
kotlin-android org.jetbrains.kotlin.android
kotlin-kapt org.jetbrains.kotlin.kapt
kotlin-parcelize org.jetbrains.kotlin.plugin.parcelize

אפשר גם לחפש יישומי פלאגין ב-Gradle Plugin Portal, ב-Maven Central Repository ובמאגר Google Maven. במאמר פיתוח פלאגינים מותאמים אישית של Gradle מוסבר בהרחבה איך פועלים מזהי הפלאגינים.

ביצוע הרפורמה

אחרי שמוצאים את המזהים של הפלאגינים שבהם אתם משתמשים, מבצעים את השלבים הבאים:

  1. אם עדיין יש לכם מאגרים של יישומי פלאגין שהוגדרו בבלוק buildscript {}, תוכלו להעביר אותם לקובץ settings.gradle במקום זאת.

  2. מוסיפים את התוספים לבלוק plugins {} בקובץ build.gradle ברמה העליונה. צריך לציין כאן את המזהה ואת גרסת הפלאגין. אם לא צריך להחיל את הפלאגין על פרויקט הבסיס, צריך להשתמש ב-apply false.

  3. מסירים את הרשומות של classpath מקובץ build.gradle.kts ברמה העליונה.

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

  5. מסירים את הקריאה apply plugin של הפלאגין מהקובץ build.gradle ברמת המודול.

לדוגמה, בהגדרה הזו נעשה שימוש בבלוק buildscript {}:

// Top-level build.gradle file
buildscript {
    repositories {
        google()
        mavenCentral()
        gradlePluginPortal()
    }
    dependencies {
        classpath("com.android.tools.build:gradle:7.4.0")
        classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.0")
        ...
    }
}

// Module-level build.gradle file
apply(plugin: "com.android.application")
apply(plugin: "kotlin-android")

זוהי הגדרה מקבילה באמצעות הבלוק plugins {}:

// Top-level build.gradle file
plugins {
   id 'com.android.application' version '7.4.0' apply false
   id 'org.jetbrains.kotlin.android' version '1.8.0' apply false
   ...
}

// Module-level build.gradle file
plugins {
   id 'com.android.application'
   id 'org.jetbrains.kotlin.android'
   ...
}

// settings.gradle
pluginManagement {
    repositories {
        google()
        mavenCentral()
        gradlePluginPortal()
    }
}

המרה של בלוק יישומי הפלאגין

החלת פלאגינים מהבלוק plugins {} דומה ב-Groovy וב-Kotlin. הקוד הבא מראה איך מחילים יישומי פלאגין ב-Groovy כשמשתמשים בקטלוגים של גרסאות:

// Top-level build.gradle file
plugins {
   alias libs.plugins.android.application apply false
   ...
}

// Module-level build.gradle file
plugins {
   alias libs.plugins.android.application
   ...
}

הקוד הבא מראה איך לעשות את אותו הדבר ב-Kotlin:

// Top-level build.gradle.kts file
plugins {
   alias(libs.plugins.android.application) apply false
   ...
}

// Module-level build.gradle.kts file
plugins {
   alias(libs.plugins.android.application)
   ...
}

הקוד הבא מראה איך להחיל יישומי פלאגין ב-Groovy כשלא משתמשים בקטלוגים של גרסאות:

// Top-level build.gradle file
plugins {
   id 'com.android.application' version '7.3.0' apply false
   ...
}

// Module-level build.gradle file
plugins {
   id 'com.android.application'
   ...
}

הקוד הבא מראה איך לעשות את זה ב-Kotlin:

// Top-level build.gradle.kts file
plugins {
   id("com.android.application") version "7.3.0" apply false
   ...
}

// Module-level build.gradle.kts file
plugins {
   id("com.android.application")
   ...
}

פרטים נוספים על הבלוק plugins {} זמינים במאמר Applying plugins בתיעוד של Gradle.

שונות

בדפי העזרה הבאים תוכלו למצוא דוגמאות קוד של Kotlin לפונקציות אחרות:

בעיות מוכרות

נכון לעכשיו, בעיה ידועה היא שעשויה להיות מהירות build איטית יותר ב-Kotlin מאשר ב-Groovy.

איך מדווחים על בעיות

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

משאבים נוספים

לדוגמה, לקובצי build של Gradle שנכתבו באמצעות Kotlin, ראו אפליקציה לדוגמה של Now ב-Android ב-GitHub.