پیکربندی ساخت خود را از Groovy به Kotlin منتقل کنید

افزونه اندروید Gradle نسخه ۴.۰ پشتیبانی از استفاده از کاتلین را در پیکربندی ساخت Gradle شما به عنوان جایگزینی برای Groovy، زبان برنامه‌نویسی که به طور سنتی در فایل‌های پیکربندی Gradle استفاده می‌شد، اضافه کرد.

کاتلین برای نوشتن اسکریپت‌های Gradle نسبت به Groovy ارجحیت دارد، زیرا کاتلین خوانایی بیشتری دارد و بررسی زمان کامپایل و پشتیبانی IDE بهتری ارائه می‌دهد.

اگرچه کاتلین در حال حاضر در مقایسه با گرووی، ادغام بهتری با ویرایشگر کد اندروید استودیو ارائه می‌دهد، اما ساخت‌هایی که از کاتلین استفاده می‌کنند، کندتر از ساخت‌هایی هستند که از گرووی استفاده می‌کنند، بنابراین هنگام تصمیم‌گیری در مورد مهاجرت، عملکرد ساخت را در نظر بگیرید.

این صفحه اطلاعات اولیه‌ای در مورد تبدیل فایل‌های ساخت Gradle برنامه اندروید شما از Groovy به Kotlin ارائه می‌دهد. برای راهنمای جامع‌تر مهاجرت، به مستندات رسمی Gradle مراجعه کنید.

گاهشمار

با شروع از Android Studio Giraffe، پروژه‌های جدید به طور پیش‌فرض از Kotlin DSL ( build.gradle.kts ) برای پیکربندی ساخت استفاده می‌کنند. این روش با برجسته‌سازی سینتکس، تکمیل کد و پیمایش به اعلان‌ها، تجربه ویرایش بهتری نسبت به Groovy DSL ( build.gradle ) ارائه می‌دهد. برای کسب اطلاعات بیشتر، به Gradle Kotlin DSL Primer مراجعه کنید.

اصطلاحات رایج

Kotlin DSL: در درجه اول به افزونه اندروید Gradle به نام Kotlin DSL یا گاهی اوقات به Gradle Kotlin DSL اصلی اشاره دارد.

در این راهنمای مهاجرت، «Kotlin» و «Kotlin DSL» به جای یکدیگر استفاده می‌شوند. به همین ترتیب، «Groovy» و «Groovy DSL» نیز به جای یکدیگر استفاده می‌شوند.

نامگذاری فایل اسکریپت

نام پسوند فایل‌های اسکریپت بر اساس زبانی است که فایل ساخت با آن نوشته شده است:

  • فایل‌های Gradle build که با Groovy نوشته می‌شوند، از پسوند .gradle استفاده می‌کنند.
  • فایل‌های Gradle build که با کاتلین نوشته شده‌اند، از پسوند .gradle.kts استفاده می‌کنند.

تبدیل سینتکس

تفاوت‌های کلی در سینتکس بین Groovy و Kotlin وجود دارد، بنابراین باید این تغییرات را در سراسر اسکریپت‌های ساخت خود اعمال کنید.

اضافه کردن پرانتز به فراخوانی متدها

Groovy به شما امکان می‌دهد در فراخوانی متدها پرانتز را حذف کنید، در حالی که Kotlin آنها را الزامی می‌داند. برای انتقال پیکربندی خود، به این نوع فراخوانی متدها پرانتز اضافه کنید. این کد نحوه پیکربندی یک تنظیم در Groovy را نشان می‌دهد:

compileSdkVersion 30

این همان کدی است که با کاتلین نوشته شده است:

compileSdkVersion(30)

اضافه کردن = به فراخوانی‌های تخصیص

Groovy DSL به شما امکان می‌دهد هنگام اختصاص ویژگی‌ها، عملگر انتساب = را حذف کنید، در حالی که کاتلین آن را الزامی می‌داند. این کد نحوه اختصاص ویژگی‌ها در Groovy را نشان می‌دهد:

java {
    sourceCompatibility JavaVersion.VERSION_17
    targetCompatibility JavaVersion.VERSION_17
}

این کد نحوه‌ی اختصاص دادن ویژگی‌ها در کاتلین را نشان می‌دهد:

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"
        

    با این حال، در کاتلین، کد قبلی toString() را روی project فراخوانی می‌کند، نه روی project.rootDir . برای دریافت مقدار دایرکتوری ریشه، عبارت ${project.rootDir} را داخل آکولاد قرار دهید:

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

    برای کسب اطلاعات بیشتر، به قالب‌های رشته‌ای در مستندات کاتلین مراجعه کنید.

تغییر نام پسوند فایل‌ها

هنگام انتقال محتویات هر فایل ساخت، پسوند .kts را به آن اضافه کنید. برای مثال، یک فایل ساخت مانند فایل settings.gradle را انتخاب کنید. نام فایل را به settings.gradle.kts تغییر دهید و محتویات فایل را به Kotlin تبدیل کنید. مطمئن شوید که پروژه شما پس از انتقال هر فایل ساخت، همچنان کامپایل می‌شود.

ابتدا کوچکترین فایل‌های خود را منتقل کنید، تجربه کسب کنید و سپس به سراغ مراحل بعدی بروید. می‌توانید ترکیبی از فایل‌های ساخت Kotlin و Groovy را در یک پروژه داشته باشید، بنابراین برای انجام این انتقال با دقت وقت بگذارید.

به جای def از val یا var استفاده کنید.

به جای def از val یا var استفاده کنید، که نحوه تعریف متغیرها در کاتلین است. این یک تعریف متغیر در Groovy است:

def building64Bit = false

این همان کدی است که با کاتلین نوشته شده است:

val building64Bit = false

پیشوند ویژگی‌های بولی با is

Groovy از منطق استنتاج ویژگی بر اساس نام ویژگی‌ها استفاده می‌کند. برای یک ویژگی بولی foo ، متدهای استنتاج شده آن می‌توانند getFoo ، setFoo یا isFoo باشند. بنابراین، پس از تبدیل به Kotlin، باید نام ویژگی‌ها را به متدهای استنتاج شده‌ای که توسط Kotlin پشتیبانی نمی‌شوند، تغییر دهید. به عنوان مثال، برای عناصر بولی buildTypes DSL، باید آنها را با پیشوند is شروع کنید. این کد نحوه تنظیم ویژگی‌های بولی در Groovy را نشان می‌دهد:

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

کد زیر همان کد در کاتلین است. توجه داشته باشید که ویژگی‌ها با پیشوند is مشخص شده‌اند.

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

تبدیل لیست‌ها و نقشه‌ها

لیست‌ها و نقشه‌ها در Groovy و Kotlin با استفاده از سینتکس‌های متفاوتی تعریف می‌شوند. Groovy از [] استفاده می‌کند، در حالی که Kotlin متدهای ایجاد مجموعه را به صراحت با استفاده از listOf یا mapOf فراخوانی می‌کند. هنگام مهاجرت، حتماً [] با listOf یا mapOf جایگزین کنید.

در اینجا نحوه تعریف لیست در Groovy در مقایسه با Kotlin آورده شده است:

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

این همان کدی است که با کاتلین نوشته شده است:

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

در اینجا نحوه تعریف یک نقشه در Groovy در مقایسه با Kotlin آورده شده است:

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

این همان کدی است که با کاتلین نوشته شده است:

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

پیکربندی انواع ساخت

در Kotlin DSL فقط انواع ساخت debug و release به صورت ضمنی در دسترس هستند. سایر انواع ساخت سفارشی باید به صورت دستی ایجاد شوند.

در Groovy می‌توانید از debug، release و برخی انواع ساخت دیگر بدون ایجاد اولیه آنها استفاده کنید. قطعه کد زیر پیکربندی انواع ساخت debug ، release و benchmark را در Groovy نشان می‌دهد.

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

برای ایجاد پیکربندی معادل در کاتلین، باید صریحاً نوع ساخت benchmark را ایجاد کنید.

buildTypes {
 debug {
   ...
 }

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

مهاجرت از بلوک buildscript به بلوک plugins

اگر پروژه شما از بلوک buildscript {} برای افزودن افزونه‌ها به پروژه استفاده می‌کند، باید آن را طوری بازسازی کنید که به جای آن از بلوک plugins {} استفاده کند. بلوک plugins {} اعمال افزونه‌ها را آسان‌تر می‌کند و با کاتالوگ‌های نسخه به خوبی کار می‌کند.

علاوه بر این، وقتی از بلوک plugins {} در فایل‌های ساخت خود استفاده می‌کنید، اندروید استودیو حتی در صورت عدم موفقیت ساخت، از زمینه (context) آگاه است. این زمینه به ایجاد اصلاحات در فایل‌های Kotlin DSL شما کمک می‌کند زیرا به Studio IDE اجازه می‌دهد تا تکمیل کد را انجام دهد و پیشنهادات مفید دیگری ارائه دهد.

شناسه‌های افزونه را پیدا کنید

در حالی که بلوک buildscript {} افزونه‌ها را با استفاده از مختصات Maven افزونه، مثلاً com.android.tools.build:gradle:7.4.0 ، به مسیر کلاس build اضافه می‌کند، بلوک plugins {} به جای آن از شناسه‌های افزونه استفاده می‌کند.

برای اکثر افزونه‌ها، شناسه افزونه رشته‌ای است که هنگام اعمال آنها با استفاده از apply plugin استفاده می‌شود. برای مثال، شناسه‌های افزونه زیر بخشی از افزونه Gradle اندروید هستند:

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

می‌توانید لیست کامل افزونه‌ها را در مخزن Google Maven پیدا کنید.

افزونه‌های کاتلین می‌توانند توسط چندین شناسه افزونه ارجاع داده شوند. توصیه می‌کنیم از شناسه افزونه با فضای نام استفاده کنید و کد را از حالت خلاصه به شناسه افزونه با فضای نام طبق جدول زیر تغییر دهید:

شناسه‌های افزونه‌های مختصرنویسی شناسه‌های افزونه با فاصله نام
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
   ...
}

کد زیر نحوه انجام همین کار را در کاتلین نشان می‌دهد:

// 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'
   ...
}

کد زیر نحوه انجام همین کار را در کاتلین نشان می‌دهد:

// 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 {} ، به بخش اعمال افزونه‌ها در مستندات Gradle مراجعه کنید.

متفرقه

برای نمونه‌های کد کاتلین و سایر قابلیت‌ها، به صفحات مستندات زیر مراجعه کنید:

مشکلات شناخته شده

در حال حاضر، یک مشکل شناخته شده این است که سرعت ساخت با Kotlin ممکن است کندتر از Groovy باشد.

نحوه گزارش مشکلات

برای دستورالعمل نحوه ارائه اطلاعات مورد نیاز برای بررسی مشکل شما، به جزئیات ابزارهای ساخت و اشکالات Gradle مراجعه کنید. سپس، با استفاده از ردیاب مشکلات عمومی گوگل، یک اشکال ثبت کنید.

منابع بیشتر

برای مشاهده‌ی یک نمونه‌ی کاربردی از فایل‌های Gradle build که با Kotlin نوشته شده‌اند، به اپلیکیشن نمونه‌ی Now In Android در گیت‌هاب مراجعه کنید.