ย้ายข้อมูลการกำหนดค่าบิลด์จาก 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) ด้วยการไฮไลต์ไวยากรณ์ การเติมโค้ดอัตโนมัติ และการไปยังการประกาศ ดูข้อมูลเพิ่มเติมได้ที่ ข้อมูลเบื้องต้นเกี่ยวกับ Kotlin DSL ของ Gradle

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

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