ย้ายข้อมูลการกำหนดค่าบิลด์จาก Groovy ไปยัง Kotlin

ปลั๊กอิน Android Gradle 4.0 ได้เพิ่มการรองรับการใช้ Kotlin ในการกำหนดค่าบิลด์ Gradle เพื่อแทนที่ Groovy ซึ่งเป็นภาษาโปรแกรมที่ ใช้กันโดยทั่วไปในไฟล์กำหนดค่า Gradle

เราขอแนะนำให้ใช้ Kotlin แทน Groovy ในการเขียนสคริปต์ Gradle เนื่องจาก Kotlin มีความสามารถดังนี้ อ่านง่ายกว่า และมีการตรวจสอบขณะคอมไพล์และการรองรับ IDE ที่ดีกว่า

แม้ว่าปัจจุบัน Kotlin จะมีการผสานรวมในโปรแกรมแก้ไขโค้ดของ Android Studio ได้ดีกว่า Groovy แต่การบิลด์ที่ใช้ Kotlin มักจะช้ากว่าการบิลด์ที่ใช้ Groovy ดังนั้นโปรดพิจารณาประสิทธิภาพการบิลด์เมื่อตัดสินใจว่าจะย้ายข้อมูลหรือไม่

หน้านี้ให้ข้อมูลพื้นฐานเกี่ยวกับการแปลงไฟล์บิลด์ Gradle ของแอป Android จาก Groovy เป็น Kotlin ดูคำแนะนำในการย้ายข้อมูลที่ครอบคลุมมากขึ้นได้ในเอกสารประกอบอย่างเป็นทางการของ Gradle

ไทม์ไลน์

ตั้งแต่ Android Studio Giraffe เป็นต้นไป โปรเจ็กต์ใหม่จะใช้ Kotlin DSL (build.gradle.kts) โดยค่าเริ่มต้นสำหรับการกำหนดค่าบิลด์ ซึ่งจะมอบประสบการณ์การแก้ไขที่ดียิ่งขึ้นกว่า Groovy DSL (build.gradle) ด้วยการไฮไลต์ไวยากรณ์ การเติมโค้ดอัตโนมัติ และการไปยังการประกาศ ดูข้อมูลเพิ่มเติมได้ที่ ข้อมูลเบื้องต้นเกี่ยวกับ Gradle Kotlin DSL

คำศัพท์ทั่วไป

Kotlin DSL: หมายถึง Android Gradle Plugin Kotlin DSL เป็นหลัก หรือบางครั้งอาจหมายถึง Gradle Kotlin DSL พื้นฐาน

ในคู่มือการย้ายข้อมูลนี้ เราจะใช้คำว่า "Kotlin" และ "Kotlin DSL" สลับกันไป ในทำนองเดียวกัน "Groovy" และ "Groovy DSL" ก็ใช้แทนกันได้

การตั้งชื่อไฟล์สคริปต์

ชื่อนามสกุลไฟล์สคริปต์จะอิงตามภาษาที่ใช้เขียนไฟล์บิลด์

  • ไฟล์บิลด์ Gradle ที่เขียนใน Groovy จะใช้นามสกุลชื่อไฟล์ .gradle
  • ไฟล์บิลด์ Gradle ที่เขียนใน Kotlin จะใช้นามสกุล.gradle.kts

แปลงไวยากรณ์

ไวยากรณ์ของ Groovy และ Kotlin มีความแตกต่างกันโดยทั่วไป ดังนั้นคุณจึงต้องใช้การเปลี่ยนแปลงเหล่านี้ในสคริปต์บิลด์ทั้งหมด

เพิ่มวงเล็บในการเรียกเมธอด

Groovy อนุญาตให้คุณละเว้นวงเล็บในการเรียกเมธอดได้ แต่ Kotlin กำหนดให้ต้องมี วงเล็บ หากต้องการย้ายข้อมูลการกำหนดค่า ให้เพิ่มวงเล็บในการเรียกใช้เมธอดประเภทนี้ โค้ดนี้แสดงวิธีกำหนดค่าในการตั้งค่าใน 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 ในแต่ละไฟล์บิลด์ขณะย้ายข้อมูลเนื้อหา เช่น เลือกไฟล์บิลด์ เช่น ไฟล์ settings.gradle เปลี่ยนชื่อไฟล์เป็น settings.gradle.kts แล้วแปลงเนื้อหาของไฟล์เป็น Kotlin ตรวจสอบว่า โปรเจ็กต์ยังคอมไพล์ได้หลังจากย้ายข้อมูลไฟล์บิลด์แต่ละไฟล์

ย้ายไฟล์ที่มีขนาดเล็กที่สุดก่อนเพื่อสั่งสมประสบการณ์ แล้วจึงย้ายไฟล์อื่นๆ ต่อไป คุณสามารถมีไฟล์บิลด์ทั้ง Kotlin และ Groovy ในโปรเจ็กต์ได้ ดังนั้นโปรดใช้เวลา ย้ายอย่างรอบคอบ

แทนที่ def ด้วย val หรือ var

แทนที่ def ด้วย val หรือ var ซึ่งเป็น วิธีกำหนดตัวแปรใน Kotlin นี่คือการประกาศตัวแปรใน Groovy

def building64Bit = false

นี่คือโค้ดเดียวกันที่เขียนใน Kotlin

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

โค้ดต่อไปนี้เป็นโค้ดเดียวกันใน Kotlin โปรดทราบว่าพร็อพเพอร์ตี้จะมีคำนำหน้าเป็น 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>"]

นี่คือโค้ดเดียวกันที่เขียนใน 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")

กำหนดค่าประเภทบิลด์

ใน Kotlin DSL จะมีเฉพาะบิลด์ประเภทการแก้ไขข้อบกพร่องและการเผยแพร่เท่านั้น โดยปริยาย ส่วนบิลด์ประเภทอื่นๆ ที่กำหนดเองจะต้องสร้างด้วยตนเอง

ใน Groovy คุณสามารถใช้บิลด์ประเภทการแก้ไขข้อบกพร่อง การเผยแพร่ และบิลด์อื่นๆ บางประเภทได้โดยไม่ต้องสร้างก่อน ข้อมูลโค้ดต่อไปนี้แสดงการกำหนดค่าที่มีประเภทบิลด์ debug, release และ benchmark ใน Groovy

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

หากต้องการสร้างการกำหนดค่าที่เทียบเท่าใน Kotlin คุณต้องสร้างประเภทบิลด์ benchmark อย่างชัดเจน

buildTypes {
 debug {
   ...
 }

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

ย้ายข้อมูลจาก buildscript ไปยังบล็อกปลั๊กอิน

หากบิลด์ใช้บล็อก buildscript {} เพื่อเพิ่มปลั๊กอินลงในโปรเจ็กต์ คุณควรปรับโครงสร้างใหม่เพื่อใช้บล็อก plugins {} แทน บล็อก plugins {} นี้ช่วยให้ใช้ปลั๊กอินได้ง่ายขึ้น และทำงานร่วมกับแคตตาล็อกเวอร์ชันได้เป็นอย่างดี

นอกจากนี้ เมื่อคุณใช้บล็อก plugins {} ในไฟล์บิลด์ Android Studio จะทราบบริบทแม้ว่าบิลด์จะล้มเหลวก็ตาม บริบทนี้ ช่วยแก้ไขไฟล์ Kotlin DSL เนื่องจากช่วยให้ IDE ของ Studio ทำการเติมโค้ดอัตโนมัติและให้คำแนะนำที่เป็นประโยชน์อื่นๆ ได้

ค้นหารหัสปลั๊กอิน

ขณะที่บล็อก buildscript {} เพิ่มปลั๊กอินลงในคลาสพาธของบิลด์โดยใช้พิกัด 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

คุณดูรายการปลั๊กอินทั้งหมดได้ในที่เก็บ Maven ของ Google

ปลั๊กอิน 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 และ ที่เก็บ Maven ของ Google อ่านการพัฒนาปลั๊กอิน 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 {} ได้ที่การใช้ ปลั๊กอิน ในเอกสารประกอบของ Gradle

เบ็ดเตล็ด

ดูตัวอย่างโค้ด Kotlin สำหรับฟังก์ชันอื่นๆ ได้ที่หน้าเอกสารประกอบต่อไปนี้

ปัญหาที่ทราบ

ปัจจุบันปัญหาที่ทราบคือความเร็วในการบิลด์อาจช้ากว่าเมื่อใช้ Kotlin มากกว่า Groovy

วิธีรายงานปัญหา

ดูวิธีการให้ข้อมูลที่เราต้องการเพื่อจัดลำดับความสำคัญของปัญหาได้ที่ รายละเอียดสำหรับข้อบกพร่องของเครื่องมือบิลด์และ Gradle จากนั้น รายงานข้อบกพร่องโดยใช้เครื่องมือติดตามปัญหาแบบสาธารณะของ Google

แหล่งข้อมูลเพิ่มเติม

ดูตัวอย่างไฟล์บิลด์ Gradle ที่เขียนด้วย Kotlin ได้ที่ แอปตัวอย่าง Now In Android ใน GitHub