ตั้งค่าปลั๊กอินไลบรารี Android Gradle สำหรับ KMP

ปลั๊กอิน Gradle com.android.kotlin.multiplatform.library เป็นเครื่องมือที่รองรับอย่างเป็นทางการสำหรับการเพิ่มเป้าหมาย Android ลงในโมดูลไลบรารี Kotlin Multiplatform (KMP) ซึ่งช่วยลดความซับซ้อนในการกำหนดค่าโปรเจ็กต์ ปรับปรุงประสิทธิภาพของบิลด์ และผสานรวมกับ Android Studio ได้ดียิ่งขึ้น

การใช้ปลั๊กอิน com.android.library สำหรับการพัฒนา KMP จะขึ้นอยู่กับ API ของปลั๊กอิน Android Gradle ที่เลิกใช้งานแล้ว และต้องเลือกใช้ในปลั๊กอิน Android Gradle 9.0 ขึ้นไป (ไตรมาสที่ 4 ปี 2025) คาดว่า API เหล่านี้จะถูกนำออกในปลั๊กอิน Android Gradle 10.0 (ครึ่งหลังของปี 2026)

หากต้องการใช้ปลั๊กอินนี้ โปรดดูส่วนใช้ปลั๊กอิน Android-KMP หากต้องการย้ายข้อมูลจาก API เดิม โปรดดูคำแนะนำในการย้ายข้อมูล

หากต้องการความช่วยเหลือเกี่ยวกับการย้ายข้อมูล AGP 9.0 ขึ้นไป คุณสามารถใช้ทักษะ Agent ที่ JetBrains สร้างขึ้นสำหรับแอป KMP ดูข้อมูลเพิ่มเติมเกี่ยวกับการใช้ทักษะใน Android Studio ได้ที่ขยายโหมด Agent ด้วยทักษะ โปรดทราบว่าผลลัพธ์จาก AI ไม่สามารถคาดเดาได้ทั้งหมด

ฟีเจอร์หลักและความแตกต่าง

ปลั๊กอิน Android-KMP ได้รับการปรับแต่งมาสำหรับโปรเจ็กต์ KMP โดยเฉพาะและแตกต่างจากปลั๊กอิน com.android.library มาตรฐานในด้านสำคัญหลายประการ ดังนี้

  • สถาปัตยกรรมตัวแปรเดียว: ปลั๊กอินใช้ตัวแปรเดียว โดยนำการรองรับเวอร์ชันผลิตภัณฑ์และประเภทบิลด์ออก ซึ่งจะช่วยลดความซับซ้อนของการกำหนดค่าและเพิ่มประสิทธิภาพของบิลด์

  • เพิ่มประสิทธิภาพสำหรับ KMP: ปลั๊กอินได้รับการออกแบบมาสำหรับไลบรารี KMP โดยมุ่งเน้นที่โค้ด Kotlin ที่ใช้ร่วมกันและความสามารถในการทำงานร่วมกัน โดยไม่รองรับบิลด์แบบเนทีฟเฉพาะ Android, AIDL และ RenderScript

  • การทดสอบที่ปิดใช้โดยค่าเริ่มต้น: ทั้งการทดสอบหน่วยและการทดสอบอุปกรณ์ (การวัดคุม) จะปิดใช้โดยค่าเริ่มต้นเพื่อเพิ่มความเร็วในการบิลด์ คุณสามารถเปิดใช้ได้หากจำเป็น

  • ไม่มีส่วนขยาย Android ระดับบนสุด: การกำหนดค่าจะจัดการด้วยบล็อก android ภายใน Gradle KMP DSL เพื่อรักษาโครงสร้างโปรเจ็กต์ KMP ที่สอดคล้องกัน ไม่มีบล็อกส่วนขยาย android ระดับบนสุด

  • เลือกใช้การคอมไพล์ Java: ระบบจะปิดใช้การคอมไพล์ Java โดยค่าเริ่มต้น ใช้ withJava() ในบล็อก android เพื่อเปิดใช้ ซึ่งจะช่วยปรับปรุงเวลาในการบิลด์เมื่อไม่จำเป็นต้องคอมไพล์ Java

ประโยชน์ของปลั๊กอินไลบรารี Android-KMP

ปลั๊กอิน Android-KMP มีประโยชน์ต่อไปนี้สำหรับโปรเจ็กต์ KMP

  • ประสิทธิภาพและความเสถียรของบิลด์ที่ดีขึ้น: ออกแบบมาเพื่อเพิ่มความเร็วในการบิลด์และเพิ่มความเสถียรภายในโปรเจ็กต์ KMP การมุ่งเน้นที่เวิร์กโฟลว์ KMP ช่วยให้กระบวนการบิลด์มีประสิทธิภาพและเชื่อถือได้มากขึ้น

  • การผสานรวม IDE ที่ดียิ่งขึ้น: ช่วยให้การเติมโค้ด การไปยังส่วนต่างๆ การแก้ไขข้อบกพร่อง และประสบการณ์การใช้งานของนักพัฒนาซอฟต์แวร์โดยรวมดีขึ้นเมื่อทำงานกับไลบรารี KMP Android

  • การกำหนดค่าโปรเจ็กต์ที่ง่ายขึ้น: ปลั๊กอินช่วยให้การกำหนดค่าสำหรับโปรเจ็กต์ KMP ง่ายขึ้นโดยการนำความซับซ้อนเฉพาะ Android ออก เช่น ตัวแปรบิลด์ ซึ่งจะทำให้ไฟล์บิลด์สะอาดและดูแลรักษาได้ง่ายขึ้น ก่อนหน้านี้ การใช้ปลั๊กอิน com.android.library ในโปรเจ็กต์ KMP อาจทำให้เกิดชื่อชุดซอร์สที่สับสน เช่น androidAndroidTest รูปแบบการตั้งชื่อนี้ไม่ค่อยเข้าใจง่ายนักสำหรับนักพัฒนาแอปที่คุ้นเคยกับโครงสร้างโปรเจ็กต์ KMP มาตรฐาน

วิธีแก้ปัญหาสำหรับฟีเจอร์ที่ไม่รองรับ

เมื่อเทียบกับการผสานรวม KMP กับปลั๊กอิน com.android.library ฟีเจอร์บางอย่างจะหายไปจากปลั๊กอิน com.android.kotlin.multiplatform.library วิธีแก้ปัญหาเบื้องต้นสำหรับฟีเจอร์ที่ไม่รองรับมีดังนี้

  • ตัวแปรบิลด์

    ระบบไม่รองรับประเภทบิลด์และเวอร์ชันผลิตภัณฑ์ เนื่องจากปลั๊กอินใหม่ใช้สถาปัตยกรรมตัวแปรเดียว ซึ่งช่วยลดความซับซ้อนของการกำหนดค่าและปรับปรุงประสิทธิภาพของบิลด์

    หากต้องการตัวแปรบิลด์ เราขอแนะนำให้สร้างโมดูลไลบรารี Android แบบสแตนด์อโลนแยกต่างหากโดยใช้ปลั๊กอิน com.android.library กำหนดค่าประเภทบิลด์และเวอร์ชันผลิตภัณฑ์ภายในโมดูลนั้น แล้วใช้เป็นทรัพยากร Dependency ของโปรเจ็กต์มาตรฐานจากชุดซอร์ส androidMain ของไลบรารี Kotlin Multiplatform ดูรายละเอียดเพิ่มเติมได้ที่หัวข้อสร้างไลบรารี Android และกำหนดค่าตัวแปรบิลด์

  • การเชื่อมโยงข้อมูลและการเชื่อมโยงมุมมอง

    ฟีเจอร์เหล่านี้เป็นฟีเจอร์เฟรมเวิร์ก UI เฉพาะของ Android ที่เชื่อมต่อกับระบบ Android View และเลย์เอาต์ XML อย่างใกล้ชิด เมื่อใช้ปลั๊กอินไลบรารี Android-KMP ใหม่ เราขอแนะนำให้คุณจัดการ UI โดยใช้เฟรมเวิร์กแบบหลายแพลตฟอร์ม เช่น Compose Multiplatform การเชื่อมโยงข้อมูลและการเชื่อมโยงมุมมองถือเป็นรายละเอียดการใช้งานของแอป Android ขั้นสุดท้าย ไม่ใช่ไลบรารีที่แชร์ได้

  • การรองรับบิลด์แบบเนทีฟ

    ปลั๊กอินใหม่จะมุ่งเน้นที่การสร้าง AAR มาตรฐานสำหรับเป้าหมาย Android การผสานรวมโค้ดแบบเนทีฟใน Kotlin Multiplatform จะได้รับการจัดการโดยตรงโดยเป้าหมายแบบเนทีฟของ KMP เอง (เช่น androidNativeArm64 และ androidNativeX86) และความสามารถในการทำงานร่วมกันของ C หากต้องการรวมโค้ด C/C++ แบบเนทีฟ คุณควรกำหนดโค้ดดังกล่าวเป็นส่วนหนึ่งของชุดซอร์สทั่วไปหรือแบบเนทีฟ และกำหนดค่า C-interop ภายในบล็อก kotlin แทนที่จะใช้กลไก externalNativeBuild เฉพาะของ Android

    หรือหากต้องการการรองรับบิลด์แบบเนทีฟผ่าน externalNativeBuild เราขอแนะนำให้สร้างโมดูล com.android.library แบบสแตนด์อโลนแยกต่างหากซึ่งคุณสามารถผสานรวมโค้ดแบบเนทีฟ และใช้ไลบรารีแบบสแตนด์อโลนนั้นจากชุดซอร์ส androidMain ของโปรเจ็กต์ไลบรารี Kotlin Multiplatform ดูรายละเอียดเพิ่มเติมได้ที่หัวข้อสร้างไลบรารี Android และเพิ่มโค้ด C และ C++ ลงในโปรเจ็กต์

  • ชั้นเรียน BuildConfig

    ฟีเจอร์ BuildConfig มีประโยชน์มากที่สุดในสภาพแวดล้อมที่มีตัวแปรหลายรายการ เนื่องจากปลั๊กอินไลบรารี Kotlin Multiplatform ใหม่ไม่ขึ้นอยู่กับตัวแปรและไม่รองรับประเภทบิลด์และเวอร์ชันผลิตภัณฑ์ จึงไม่มีการใช้ฟีเจอร์นี้ เราขอแนะนำให้ใช้ปลั๊กอิน BuildKonfig หรือโซลูชันชุมชนที่คล้ายกันเพื่อสร้างข้อมูลเมตาสำหรับเป้าหมายทั้งหมดแทน

สิ่งที่ต้องมีก่อน

หากต้องการใช้ปลั๊กอิน com.android.kotlin.multiplatform.library คุณต้องกำหนดค่าโปรเจ็กต์ด้วยเวอร์ชันขั้นต่ำต่อไปนี้หรือสูงกว่า

  • ปลั๊กอิน Android Gradle (AGP): 8.10.0
  • Kotlin Gradle Plugin (KGP): 2.0.0

ใช้ปลั๊กอิน Android-KMP กับโมดูลที่มีอยู่

หากต้องการใช้ปลั๊กอิน Android-KMP กับโมดูลไลบรารี KMP ที่มีอยู่ ให้ทำตามขั้นตอนต่อไปนี้

  1. ประกาศปลั๊กอินในแคตตาล็อกเวอร์ชัน เปิดไฟล์ TOML ของแคตตาล็อกเวอร์ชัน (โดยปกติคือ gradle/libs.versions.toml) แล้วเพิ่มส่วนคำจำกัดความของปลั๊กอิน ดังนี้

    # To check the version number of the latest Kotlin release, go to
    # https://kotlinlang.org/docs/releases.html
    
    [versions]
    androidGradlePlugin = "9.4.0"
    kotlin = "KOTLIN_VERSION"
    
    [plugins]
    kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
    android-kotlin-multiplatform-library = { id = "com.android.kotlin.multiplatform.library", version.ref = "androidGradlePlugin" }
    
  2. ใช้การประกาศปลั๊กอินในไฟล์บิลด์ระดับรูท เปิดไฟล์ build.gradle.kts ที่อยู่ในไดเรกทอรีรากของโปรเจ็กต์ เพิ่มชื่อแทนของปลั๊กอินลงในบล็อก plugins โดยใช้ apply false ซึ่งจะทำให้อีเมลแทนของปลั๊กอินพร้อมใช้งานสำหรับโปรเจ็กต์ย่อยทั้งหมดโดยไม่ต้องใช้ตรรกะของปลั๊กอินกับโปรเจ็กต์รูทเอง

    Kotlin

    // Root build.gradle.kts file
    
    plugins {
       alias(libs.plugins.kotlin.multiplatform) apply false
    
       // Add the following
       alias(libs.plugins.android.kotlin.multiplatform.library) apply false
    }

    ดึงดูด

    // Root build.gradle file
    
    plugins {
       alias(libs.plugins.kotlin.multiplatform) apply false
    
       // Add the following
       alias(libs.plugins.android.kotlin.multiplatform.library) apply false
    }
  3. ใช้ปลั๊กอินในไฟล์บิลด์โมดูลไลบรารี KMP เปิดไฟล์ build.gradle.kts ในโมดูลไลบรารี KMP แล้วใช้ปลั๊กอินที่ด้านบนของไฟล์ภายในบล็อก plugins ดังนี้

    Kotlin

    // Module-specific build.gradle.kts file
    
    plugins {
       alias(libs.plugins.kotlin.multiplatform)
    
       // Add the following
       alias(libs.plugins.android.kotlin.multiplatform.library)
    }

    ดึงดูด

    // Module-specific build.gradle file
    
    plugins {
       alias(libs.plugins.kotlin.multiplatform)
    
       // Add the following
       alias(libs.plugins.android.kotlin.multiplatform.library)
    }
  4. กำหนดค่าเป้าหมาย KMP ของ Android กำหนดค่าบล็อก Kotlin Multiplatform (kotlin) เพื่อกำหนดเป้าหมาย Android ภายในบล็อก kotlin ให้ระบุเป้าหมาย Android โดยใช้ android ดังนี้

    Kotlin

    kotlin {
       android {
           namespace = "com.example.kmpfirstlib"
           compileSdk = 33
           minSdk = 24
    
           withJava() // enable java compilation support
           withHostTestBuilder {}.configure {}
           withDeviceTestBuilder {
               sourceSetTreeName = "test"
           }
    
           compilerOptions.configure {
               jvmTarget.set(
                   org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_1_8
               )
           }
       }
    
       sourceSets {
           androidMain {
               dependencies {
                   // Add Android-specific dependencies here
               }
           }
           getByName("androidHostTest") {
               dependencies {
               }
           }
    
           getByName("androidDeviceTest") {
               dependencies {
               }
           }
       }
       // ... other targets (JVM, iOS, etc.) ...
    }

    ดึงดูด

    kotlin {
       android {
           namespace = "com.example.kmpfirstlib"
           compileSdk = 33
           minSdk = 24
    
           withJava() // enable java compilation support
           withHostTestBuilder {}.configure {}
           withDeviceTestBuilder {
               it.sourceSetTreeName = "test"
           }
    
           compilerOptions.options.jvmTarget.set(
               org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_1_8
           )
       }
    
       sourceSets {
           androidMain {
               dependencies {
               }
           }
           androidHostTest {
               dependencies {
               }
           }
           androidDeviceTest {
               dependencies {
               }
           }
       }
       // ... other targets (JVM, iOS, etc.) ...
    }
  5. ใช้การเปลี่ยนแปลง หลังจากใช้ปลั๊กอินและกำหนดค่าบล็อก kotlin แล้ว ให้ซิงค์โปรเจ็กต์ Gradle เพื่อใช้การเปลี่ยนแปลง

ย้ายข้อมูลจากปลั๊กอินเดิม

คู่มือนี้จะช่วยคุณย้ายข้อมูลจากปลั๊กอิน com.android.library เดิมไปยังปลั๊กอิน com.android.kotlin.multiplatform.library

1. ย้ายแหล่งข้อมูล

ปลั๊กอินเดิมอนุญาตให้คุณใช้ชุดแหล่งที่มา src/main, src/test และ src/androidTest นอกเหนือจาก src/androidMain, src/androidHostTest และ src/androidDeviceTest ปลั๊กอินใหม่จะใช้เฉพาะไดเรกทอรีต้นทางหลังเท่านั้น ดังนั้นคุณจะต้องย้ายแหล่งที่มาจาก src/main ไปยัง src/androidMain, จาก src/test ไปยัง src/androidHostTest และจาก src/androidTest ไปยัง src/androidDeviceTest

2. กำหนดค่าไดเรกทอรีแหล่งที่มาและทรัพยากรที่กำหนดเอง

หากคุณมีแหล่งที่มาหรือทรัพยากรในไดเรกทอรีที่ไม่ได้มาตรฐาน ก่อนหน้านี้คุณได้กำหนดค่าโดยใช้บล็อก sourceSets เมื่อใช้ปลั๊กอินใหม่ ให้ใช้ส่วนขยาย androidComponents เพื่อเพิ่มไดเรกทอรีต้นทางแบบคงที่ลงในตัวแปร

โปรดทราบว่าเมื่อใช้ปลั๊กอินใหม่ เมธอด addStaticSourceDirectory จะเพิ่มไดเรกทอรีลงในรายการไดเรกทอรีต้นทางที่มีอยู่ เมื่อใช้ปลั๊กอินเดิม เมธอด setSrcDirs จะแทนที่รายการ ส่วนเมธอด srcDir จะเพิ่มรายการ

Android-KMP

เมื่อใช้ปลั๊กอินใหม่ ให้ใช้บล็อก onVariants เพื่อโต้ตอบกับแหล่งที่มาของตัวแปร

// build.gradle.kts

androidComponents {
    onVariants { variant ->
        // Add a directory for Kotlin sources
        variant.sources.kotlin?.addStaticSourceDirectory("other/kotlin")

        // Add a directory for Android assets
        variant.sources.assets?.addStaticSourceDirectory("other/assets")
    }
}

ปลั๊กอินเดิม

เมื่อใช้ปลั๊กอิน com.android.library ระบบจะใช้บล็อก sourceSets เพื่อตั้งค่าหรือเพิ่มไดเรกทอรีต้นทาง

// build.gradle.kts

android {
    sourceSets {
        getByName("main") {
            // Replaces the directory for Kotlin sources.
            kotlin.setSrcDirs(listOf("other/kotlin"))

            // Appends a directory for assets.
            assets.srcDir("other/assets")
        }
    }
}

3. ประกาศทรัพยากร Dependency

งานที่พบบ่อยคือการประกาศทรัพยากร Dependency สำหรับชุดซอร์สเฉพาะของ Android ปลั๊กอินใหม่กำหนดให้ต้องวางโค้ดเหล่านี้ไว้ภายในบล็อก sourceSets อย่างชัดเจน ซึ่งต่างจากบล็อก dependencies ทั่วไปที่ใช้ก่อนหน้านี้

Android-KMP

ปลั๊กอินใหม่จะช่วยให้โครงสร้างสะอาดขึ้นโดยการจัดกลุ่มทรัพยากร Dependency ของ Android ภายในชุดซอร์ส androidMain นอกจากชุดซอร์สหลักแล้ว ยังมีชุดซอร์สทดสอบ 2 ชุดที่สร้างขึ้นตามต้องการ ได้แก่ androidDeviceTest และ androidHostTest (ดูข้อมูลเพิ่มเติมได้ที่การกำหนดค่าการทดสอบโฮสต์และอุปกรณ์)

// build.gradle.kts

kotlin {
    android {}
    //... other targets

    sourceSets {
        commonMain.dependencies {
            implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0")
        }

        // Dependencies are now scoped to the specific Android source set
        androidMain.dependencies {
            implementation("androidx.appcompat:appcompat:1.7.0")
            implementation("com.google.android.material:material:1.11.0")
        }
    }
}

ชุดซอร์สมีการคอมไพล์ Kotlin ที่เกี่ยวข้องซึ่งชื่อ main, deviceTest และ hostTest คุณกำหนดค่าชุดซอร์สและการคอมไพล์ได้ในสคริปต์บิลด์ดังนี้

// build.gradle.kts

kotlin {
    android {
        compilations.getByName("deviceTest") {
            kotlinOptions.languageVersion = "2.0"
        }
    }
}

ปลั๊กอินเดิม

เมื่อใช้ปลั๊กอินเดิม คุณสามารถประกาศทรัพยากร Dependency เฉพาะ Android ในบล็อกทรัพยากร Dependency ระดับบนสุด ซึ่งบางครั้งอาจทำให้สับสนในโมดูลแบบหลายแพลตฟอร์ม

// build.gradle.kts

kotlin {
  androidTarget()
  //... other targets
}

// Dependencies for all source sets were often mixed in one block
dependencies {
  // Common dependencies
  commonMainImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0")

  // Android-specific dependencies
  implementation("androidx.appcompat:appcompat:1.7.0")
  implementation("com.google.android.material:material:1.11.0")
}

4. เปิดใช้แหล่งข้อมูล Android

ระบบจะไม่เปิดใช้การรองรับทรัพยากร Android (โฟลเดอร์ res) โดยค่าเริ่มต้นด้วยปลั๊กอินใหม่เพื่อเพิ่มประสิทธิภาพการบิลด์ คุณต้องเลือกใช้เพื่อใช้งานฟีเจอร์นี้ การเปลี่ยนแปลงนี้ช่วยให้มั่นใจได้ว่าโปรเจ็กต์ที่ไม่ต้องใช้ทรัพยากรเฉพาะของ Android จะไม่ได้รับภาระจากค่าใช้จ่ายเพิ่มเติมในการบิลด์ที่เกี่ยวข้อง

Android-KMP

คุณต้องเปิดใช้การประมวลผลทรัพยากร Android อย่างชัดเจน ควรวางทรัพยากรไว้ใน src/androidMain/res

// build.gradle.kts

kotlin {
  android {
    // ...
    // Enable Android resource processing
    androidResources {
      enable = true
    }
  }
}

// Project Structure
// └── src
//     └── androidMain
//         └── res
//             ├── values
//             │   └── strings.xml
//             └── drawable
//                 └── icon.xml

ปลั๊กอินเดิม

ระบบจะเปิดใช้การประมวลผลทรัพยากรโดยค่าเริ่มต้น คุณสามารถเพิ่มไดเรกทอรี res ใน src/main และเริ่มเพิ่ม XML ที่ถอนออกได้ ค่าต่างๆ และอื่นๆ ได้ทันที

// build.gradle.kts

android {
    namespace = "com.example.library"
    compileSdk = 34
    // No extra configuration was needed to enable resources.
}

// Project Structure
// └── src
//     └── main
//         └── res
//             ├── values
//             │   └── strings.xml
//             └── drawable
//                 └── icon.xml

5. กำหนดค่าการทดสอบโฮสต์และอุปกรณ์

โดยค่าเริ่มต้น ปลั๊กอินใหม่จะปิดใช้การทดสอบฝั่งโฮสต์ (หน่วย) และฝั่งอุปกรณ์ (วัดคุม) ของ Android คุณต้องเลือกใช้เพื่อสร้างชุดซอร์สและการกำหนดค่าการทดสอบอย่างชัดเจน ในขณะที่ปลั๊กอินเดิมจะสร้างชุดซอร์สและการกำหนดค่าการทดสอบโดยอัตโนมัติ

โมเดลการเลือกใช้นี้ช่วยยืนยันว่าโปรเจ็กต์ของคุณยังคงมีขนาดเล็กและมีเฉพาะตรรกะการสร้างและชุดซอร์สที่คุณใช้งานอยู่เท่านั้น

Android-KMP

ปลั๊กอินใหม่ช่วยให้คุณเปิดใช้และกำหนดค่าการทดสอบภายในบล็อก kotlin.android ได้ วิธีนี้จะทำให้การตั้งค่าชัดเจนยิ่งขึ้นและหลีกเลี่ยงการสร้างคอมโพเนนต์ทดสอบที่ไม่ได้ใช้ ชุดซอร์ส androidUnitTest จะกลายเป็น androidHostTest (ไดเรกทอรีทดสอบเปลี่ยนจาก src/androidUnitTest เป็น src/androidHostTest) และ androidInstrumentedTest จะกลายเป็น androidDeviceTest (ไดเรกทอรีทดสอบเปลี่ยนจาก src/androidInstrumentedTest เป็น src/androidDeviceTest)

// build.gradle.kts

kotlin {
  android {
    // ...

    // Opt-in to enable and configure host-side (unit) tests
    withHostTest {
      isIncludeAndroidResources = true
    }

    // Opt-in to enable and configure device-side (instrumented) tests
    withDeviceTest {
      instrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
      execution = "HOST"
    }
  }
}

// Project Structure (After Opt-in)
// └── src
//     ├── androidHostTest
//     └── androidDeviceTest

ปลั๊กอินเดิม

เมื่อใช้ปลั๊กอิน com.android.library ระบบจะสร้างชุดซอร์ส androidUnitTest และ androidInstrumentedTest โดยค่าเริ่มต้น คุณกำหนดค่าลักษณะการทำงานภายในบล็อก android โดยปกติจะใช้ DSL testOptions

// build.gradle.kts

android {
  defaultConfig {
    // Runner was configured in defaultConfig
    testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
  }

  testOptions {
    // Configure unit tests (for the 'test' source set)
    unitTests.isIncludeAndroidResources = true

    // Configure device tests (for the 'androidTest' source set)
    execution = "HOST"
  }
}

// Project Structure (Defaults)
// └── src
//     ├── test
//     └── androidTest

6. เปิดใช้การคอมไพล์แหล่งที่มาของ Java

หากไลบรารี KMP ของคุณต้องคอมไพล์แหล่งที่มา Java สำหรับเป้าหมาย Android คุณต้องเปิดใช้ฟังก์ชันนี้อย่างชัดแจ้งด้วยปลั๊กอินใหม่ โปรดทราบว่าการดำเนินการนี้จะเปิดใช้การคอมไพล์สำหรับไฟล์ Java ที่อยู่ในโปรเจ็กต์โดยตรง ไม่ใช่สำหรับทรัพยากร Dependency วิธีการตั้งค่าเวอร์ชันเป้าหมาย JVM ของคอมไพเลอร์ Java และ Kotlin ก็มีการเปลี่ยนแปลงเช่นกัน

Android-KMP

คุณต้องเลือกใช้การคอมไพล์ Java โดยเรียกใช้ withJava() ตอนนี้เป้าหมาย JVM ได้รับการกำหนดค่าโดยตรงภายในบล็อก kotlin { android {} } เพื่อให้การตั้งค่าเป็นหนึ่งเดียวกันมากขึ้น การตั้งค่า jvmTarget ที่นี่จะมีผลกับการคอมไพล์ทั้ง Kotlin และ Java สำหรับเป้าหมาย Android

// build.gradle.kts

kotlin {
  android {
    //  Opt-in to enable Java source compilation
    withJava()
    // Configure the JVM target for both Kotlin and Java sources
    compilerOptions {
      jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_1_8)
    }
  }
  // ...
}

// Project Structure:
// └── src
//     └── androidMain
//         ├── kotlin
//         │   └── com/example/MyKotlinClass.kt
//         └── java
//             └── com.example/MyJavaClass.java

ปลั๊กอินเดิม

การคอมไพล์ Java จะเปิดใช้โดยค่าเริ่มต้น เป้าหมาย JVM สำหรับทั้งแหล่งที่มา Java และ Kotlin ได้รับการตั้งค่าในบล็อก Android โดยใช้ compileOptions

// build.gradle.kts

android {
  // ...
  compileOptions {
    sourceCompatibility = JavaVersion.VERSION_1_8
    targetCompatibility = JavaVersion.VERSION_1_8
  }
}

kotlin {
  androidTarget {
    compilations.all {
      kotlinOptions.jvmTarget = "1.8"
    }
  }
}

7. โต้ตอบกับตัวแปรบิลด์โดยใช้ androidComponents

ส่วนขยาย androidComponents ยังคงพร้อมใช้งานสำหรับการโต้ตอบกับอาร์ติแฟกต์บิลด์แบบเป็นโปรแกรม แม้ว่า Variant API ส่วนใหญ่จะยังคงเหมือนเดิม แต่อินเทอร์เฟซ AndroidKotlinMultiplatformVariant ใหม่จะมีข้อจำกัดมากกว่าเนื่องจากปลั๊กอินจะสร้างตัวแปรเพียงรายการเดียว

ด้วยเหตุนี้ พร็อพเพอร์ตี้ที่เกี่ยวข้องกับประเภทบิลด์และเวอร์ชันผลิตภัณฑ์จึงไม่พร้อมใช้งานในออบเจ็กต์ตัวแปรอีกต่อไป

Android-KMP

ตอนนี้บล็อก onVariants จะทำซ้ำตัวแปรเดียว คุณยังคงเข้าถึงพร็อพเพอร์ตี้ทั่วไป เช่น name และ artifacts ได้ แต่จะเข้าถึงพร็อพเพอร์ตี้เฉพาะประเภทบิลด์ไม่ได้

// build.gradle.kts

androidComponents {
  onVariants { variant ->
      val artifacts = variant.artifacts
  }
}

ปลั๊กอินเดิม

เมื่อมีตัวแปรหลายรายการ คุณจะเข้าถึงพร็อพเพอร์ตี้เฉพาะประเภทบิลด์เพื่อกำหนดค่างานได้

// build.gradle.kts

androidComponents {
  onVariants(selector().withBuildType("release")) { variant ->
    // ...
  }
}

8. เลือกตัวแปรของทรัพยากร Dependency ของไลบรารี Android

ไลบรารี KMP สร้างตัวแปรเดียวสำหรับ Android อย่างไรก็ตาม คุณอาจต้องใช้ไลบรารี Android มาตรฐาน (com.android.library) ที่มีตัวแปรหลายรายการ (เช่น เวอร์ชันผลิตภัณฑ์ free/paid) การควบคุมวิธีที่โปรเจ็กต์เลือกตัวแปรจากการขึ้นต่อกันนั้นเป็นข้อกำหนดที่พบบ่อย

Android-KMP

ปลั๊กอินใหม่จะรวมศูนย์และชี้แจงตรรกะนี้ภายในบล็อก kotlin.android.localDependencySelection ซึ่งจะช่วยให้เห็นชัดเจนยิ่งขึ้นว่าระบบจะเลือกทรัพยากร Dependency ภายนอกตัวแปรใดสำหรับไลบรารี KMP ตัวแปรเดียว

// build.gradle.kts
kotlin {
  android {
    localDependencySelection {
      // For dependencies with multiple build types, select 'debug' first, and 'release' in case 'debug' is missing
      selectBuildTypeFrom.set(listOf("debug", "release"))

      // For dependencies with a 'type' flavor dimension...
      productFlavorDimension("type") {
        // ...select the 'typeone' flavor.
        selectFrom.set(listOf("typeone"))
      }
    }
  }
}

ปลั๊กอินเดิม

คุณกำหนดค่ากลยุทธ์การเลือกทรัพยากร Dependency ภายในบล็อก buildTypes and productFlavors ซึ่งมักเกี่ยวข้องกับการใช้ missingDimensionStrategy เพื่อระบุตัวแปรเริ่มต้นสำหรับมิติข้อมูลที่ไลบรารีของคุณไม่มี หรือ matchingFallbacks ภายในตัวแปรที่เฉพาะเจาะจงเพื่อกำหนดลำดับการค้นหา

โปรดดูข้อมูลโดยละเอียดเพิ่มเติมเกี่ยวกับการใช้งาน API ที่หัวข้อแก้ไขข้อผิดพลาดในการจับคู่

9. เพิ่มทรัพยากร Dependency ของตัวอย่าง Compose

โดยปกติแล้ว เราต้องการให้ไลบรารีที่เฉพาะเจาะจงกำหนดขอบเขตไว้ในสภาพแวดล้อมในการพัฒนาซอฟต์แวร์ในเครื่อง เพื่อป้องกันไม่ให้เครื่องมือภายในรั่วไหลไปยังอาร์ติแฟกต์ที่เผยแพร่ขั้นสุดท้าย ซึ่งจะกลายเป็นปัญหาเมื่อใช้ปลั๊กอิน Android ของ KMP ใหม่ เนื่องจากปลั๊กอินนี้จะนำสถาปัตยกรรมประเภทบิลด์ที่ใช้แยกทรัพยากร Dependency ของการพัฒนาออกจากโค้ดเวอร์ชันที่เผยแพร่ออกไป

Android-KMP

หากต้องการเพิ่มทรัพยากร Dependency สำหรับการพัฒนาและการทดสอบในเครื่องเท่านั้น ให้เพิ่มทรัพยากร Dependency ลงในการกำหนดค่า classpath ของรันไทม์โดยตรง (ในบล็อก dependencies ระดับบนสุด) ของการคอมไพล์ Android หลัก ซึ่งจะช่วยให้มั่นใจได้ว่าทรัพยากร Dependency จะพร้อมใช้งานที่รันไทม์ (เช่น สำหรับเครื่องมืออย่างตัวอย่างการเขียน) แต่ไม่ได้เป็นส่วนหนึ่งของคลาสพาธการคอมไพล์หรือ API ที่เผยแพร่ของไลบรารี

// build.gradle.kts
dependencies {
  "androidRuntimeClasspath"(libs.androidx.compose.ui.tooling)
}

ปลั๊กอินเดิม

โปรเจ็กต์ Kotlin Multiplatform ที่ใช้ปลั๊กอิน com.android.library สำหรับเป้าหมาย Android ควรใช้การกำหนดค่า debugImplementation ซึ่งจะกำหนดขอบเขตของทรัพยากร Dependency เป็นประเภทบิลด์การแก้ไขข้อบกพร่อง และป้องกันไม่ให้รวมไว้ในตัวแปรของรุ่นของไลบรารีที่ผู้บริโภคใช้

// build.gradle.kts
dependencies {
  debugImplementation(libs.androidx.compose.ui.tooling)
}

10. กำหนดค่าเป้าหมาย JVM สำหรับเป้าหมาย Android ของ KMP

ปลั๊กอิน Android KMP จะตั้งค่าเป้าหมาย JVM โดยใช้ android.compilerOptions.jvmTarget ซึ่งใช้ได้กับทั้ง Java และ Kotlin ซึ่งช่วยให้การกำหนดค่าง่ายขึ้นเมื่อเทียบกับบล็อก compileOptions และ kotlinOptions แยกต่างหากในโปรเจ็กต์ Android แบบล้วนๆ

Android-KMP

เมื่อทำงานกับโปรเจ็กต์ Kotlin Multiplatform (KMP) ที่มีเป้าหมาย Android คุณมีหลายวิธีในการกำหนดค่าเวอร์ชันเป้าหมาย JVM สำหรับทั้งคอมไพเลอร์ Kotlin และ Java การทำความเข้าใจขอบเขตและลำดับชั้นของการกำหนดค่าเหล่านี้เป็นกุญแจสำคัญในการจัดการความเข้ากันได้ของไบต์โค้ดของโปรเจ็กต์

วิธีหลัก 3 วิธีในการตั้งค่าเป้าหมาย JVM มีดังนี้ โดยเรียงลำดับจากความสำคัญต่ำสุดไปสูงสุด ค่าเป้าหมาย JVM ที่มีลำดับความสำคัญสูงกว่าจะมีผลกับชุดย่อยที่เล็กลงของเป้าหมายที่กำหนดค่าไว้ และลบล้างค่าที่มีลำดับความสำคัญต่ำกว่า ซึ่งหมายความว่าคุณสามารถตั้งค่า JVM เวอร์ชันต่างๆ สำหรับเป้าหมายและการคอมไพล์ภายในเป้าหมายในโปรเจ็กต์ได้

การใช้ Toolchain ของ Kotlin (ลำดับความสำคัญต่ำสุด)

วิธีที่ใช้กันมากที่สุดในการตั้งค่าเป้าหมาย JVM คือการระบุ Toolchain ในบล็อก kotlin ของไฟล์ build.gradle.kts แนวทางนี้จะกำหนดเป้าหมายสำหรับทั้งงานการคอมไพล์ Kotlin และ Java ในเป้าหมายที่ใช้ JVM ทั้งหมดในโปรเจ็กต์ รวมถึง Android

// build.gradle.kts
kotlin {
    jvmToolchain(21)
}

การกำหนดค่านี้ทำให้ทั้ง kotlinc และ javac กำหนดเป้าหมายเป็น JVM 21 ซึ่งเป็นวิธีที่ยอดเยี่ยมในการสร้างเกณฑ์พื้นฐานที่สอดคล้องกันสำหรับทั้งโปรเจ็กต์

การใช้ตัวเลือกคอมไพเลอร์ระดับเป้าหมายของ Android (ลำดับความสำคัญปานกลาง)

คุณสามารถระบุเป้าหมาย JVM สำหรับเป้าหมาย Android KMP โดยเฉพาะภายในบล็อก android การตั้งค่านี้จะลบล้างการกำหนดค่า jvmToolchain ทั่วทั้งโปรเจ็กต์และมีผลกับการคอมไพล์ Android ทั้งหมด

// build.gradle.kts
kotlin {
    android {
        compilerOptions {
            jvmTarget.set(JvmTarget.JVM_11)
        }
    }
}

ในกรณีนี้ แม้ว่าจะตั้งค่า jvmToolchain เป็นเวอร์ชันอื่น แต่โค้ด Kotlin และ Java ของเป้าหมาย Android จะได้รับการคอมไพล์เพื่อกำหนดเป้าหมาย JVM 11

การใช้ตัวเลือกคอมไพเลอร์ระดับการคอมไพล์ (ลำดับความสำคัญสูงสุด)

หากต้องการการควบคุมที่ละเอียดยิ่งขึ้น คุณสามารถกำหนดค่าตัวเลือกคอมไพเลอร์ตามการคอมไพล์แต่ละครั้ง (เช่น ใน androidMain หรือ androidHostTest เท่านั้น) ซึ่งจะเป็นประโยชน์หากการคอมไพล์ที่เฉพาะเจาะจงต้องกำหนดเป้าหมายเป็น JVM เวอร์ชันอื่น การตั้งค่านี้จะลบล้างทั้ง Toolchain ของ Kotlin และตัวเลือกระดับเป้าหมายของ Android

// build.gradle.kts
kotlin {
    android {
        compilations.all {
            compileTaskProvider.configure {
                compilerOptions.jvmTarget.set(JvmTarget.JVM_11)
            }
        }
    }
}

การกำหนดค่านี้ช่วยให้มั่นใจว่าการคอมไพล์ทั้งหมดภายในเป้าหมาย Android ใช้ JVM 11 ซึ่งช่วยให้ควบคุมได้อย่างละเอียด

ปลั๊กอินเดิม

ในโปรเจ็กต์ KMP ที่ใช้ปลั๊กอินไลบรารี Android มาตรฐาน (com.android.library) การกำหนดค่าจะแตกต่างจากเมื่อคุณใช้ปลั๊กอิน Android ของ KMP เล็กน้อย (แต่มีแนวคิดคล้ายกัน)

การใช้ Toolchain ของ Kotlin

เมธอด kotlin.jvmToolchain() ทำงานเหมือนกัน โดยตั้งค่า sourceCompatibility และ targetCompatibility สำหรับ Java และ jvmTarget สำหรับ Kotlin เราขอแนะนำให้ใช้วิธีนี้

// build.gradle.kts
kotlin {
    jvmToolchain(21)
}

compileOptions และ kotlinOptions

หากไม่ได้ใช้ Toolchain ของ Kotlin คุณต้องกำหนดค่าเป้าหมาย JVM โดยใช้บล็อกแยกต่างหากสำหรับ Java และ Kotlin

// build.gradle.kts
android {
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_11
        targetCompatibility = JavaVersion.VERSION_11
    }

    kotlinOptions {
        jvmTarget = "11"
    }
}

11. เผยแพร่กฎการเก็บรักษาของผู้ใช้

หากไลบรารี KMP ของคุณจำเป็นต้องจัดส่งกฎการเก็บรักษาของผู้บริโภค (เช่น กฎ ProGuard สำหรับ R8) ให้กับผู้บริโภค คุณต้องเปิดใช้การเผยแพร่อย่างชัดเจนด้วยปลั๊กอินใหม่ ก่อนหน้านี้ ระบบจะเผยแพร่กฎการเก็บรักษาของผู้บริโภคโดยค่าเริ่มต้นหากมีการระบุไว้

Android-KMP

เมื่อใช้ปลั๊กอินใหม่ คุณต้องตั้งค่า optimization.consumerKeepRules.publish = true และระบุไฟล์กฎ ภายในบล็อก consumerKeepRules เพื่อเผยแพร่กฎการเก็บรักษาของผู้ใช้

// build.gradle.kts
kotlin {
  android {
    optimization {
      consumerKeepRules.apply {
        publish = true
        file("consumer-proguard-rules.pro")
      }
    }
  }
}

ปลั๊กอินเดิม

เมื่อใช้ com.android.library ไฟล์กฎที่ระบุด้วย consumerProguardFiles ใน android.defaultConfig จะเผยแพร่ในอาร์ติแฟกต์ของไลบรารีโดยค่าเริ่มต้น

// build.gradle.kts
android {
  defaultConfig {
    consumerProguardFiles("consumer-proguard-rules.pro")
  }
}

12. เผยแพร่ไลบรารีไปยัง Maven

หากคุณวางแผนที่จะเผยแพร่ไลบรารี KMP ไปยัง Maven เพื่อให้โปรเจ็กต์อื่นๆ ใช้งาน กระบวนการจะแตกต่างกันไปขึ้นอยู่กับว่าคุณใช้ปลั๊กอิน Android-KMP ใหม่หรือปลั๊กอินเดิม

Android-KMP

ปลั๊กอิน com.android.kotlin.multiplatform.library ผสานรวมกับกลไกการเผยแพร่ Kotlin Multiplatform มาตรฐาน ไม่มีขั้นตอนเฉพาะสำหรับ Android ที่จำเป็นนอกเหนือจากกระบวนการเผยแพร่ไลบรารี KMP มาตรฐาน

หากต้องการเผยแพร่ไลบรารี ให้ทำตามเอกสารประกอบอย่างเป็นทางการของ JetBrains: ตั้งค่าการเผยแพร่สำหรับไลบรารีแบบหลายแพลตฟอร์ม

ปลั๊กอินเดิม

เมื่อใช้ com.android.library สำหรับเป้าหมาย Android ในโปรเจ็กต์ KMP คุณต้องทำตามคู่มือการเผยแพร่ไลบรารี Android มาตรฐานเพื่อเตรียมและเผยแพร่อาร์ติแฟกต์เฉพาะ Android (.aar)

ดูวิธีการอย่างละเอียดได้ที่เตรียมไลบรารีให้พร้อมสำหรับการเผยแพร่

เอกสารอ้างอิง API ของปลั๊กอิน

ปลั๊กอินใหม่มีแพลตฟอร์ม API ที่แตกต่างจาก com.android.library ดูข้อมูลโดยละเอียดเกี่ยวกับ DSL และอินเทอร์เฟซใหม่ได้ในเอกสารอ้างอิง API ดังนี้

ปัญหาที่ทราบเกี่ยวกับปลั๊กอินไลบรารี Android-KMP

ปัญหาที่ทราบซึ่งอาจเกิดขึ้นเมื่อคุณใช้ปลั๊กอิน com.android.kotlin.multiplatform.library ใหม่มีดังนี้