KMP के लिए Android Gradle लाइब्रेरी प्लग इन सेट अप करना

com.android.kotlin.multiplatform.library Gradle प्लगिन, Kotlin Multiplatform (KMP) लाइब्रेरी मॉड्यूल में Android टारगेट जोड़ने के लिए, आधिकारिक तौर पर उपलब्ध टूल है. इससे प्रोजेक्ट को आसानी से कॉन्फ़िगर किया जा सकता है. साथ ही, बिल्ड की परफ़ॉर्मेंस बेहतर होती है और Android Studio के साथ बेहतर तरीके से इंटिग्रेट किया जा सकता है.

अब प्लगिन का इस्तेमाल किया जाता है. इसे Android-KMP प्लगिन भी कहा जाता है. JetBrains, KMP के लिए com.android.library प्लगिन का इस्तेमाल जारी रखने की सुविधा नहीं देगा. साथ ही, आपको आने वाले समय में होने वाले अपडेट और सुधारों का फ़ायदा नहीं मिलेगा.

इस प्लगिन को लागू करने के लिए, Android-KMP प्लगिन लागू करना सेक्शन देखें. अगर आपको लेगसी एपीआई से माइग्रेट करना है, तो माइग्रेशन गाइड देखें.

मुख्य सुविधाएं और अंतर

Android-KMP प्लगिन को खास तौर पर KMP प्रोजेक्ट के लिए बनाया गया है. यह कई मामलों में, स्टैंडर्ड com.android.library प्लगिन से अलग है:

  • सिंगल वैरिएंट आर्किटेक्चर: यह प्लगिन, एक ही वैरिएंट का इस्तेमाल करता है. इससे ऐप्लिकेशन टाइप और बिल्ड के तरीके के लिए सहायता हट जाती है. इससे कॉन्फ़िगरेशन आसान हो जाता है और बिल्ड की परफ़ॉर्मेंस बेहतर हो जाती है.

  • KMP के लिए ऑप्टिमाइज़ किया गया: इस प्लगिन को KMP लाइब्रेरी के लिए डिज़ाइन किया गया है. इसमें शेयर किए गए Kotlin कोड और इंटरऑपरेबिलिटी पर फ़ोकस किया गया है. साथ ही, इसमें Android के लिए खास तौर पर बनाए गए नेटिव बिल्ड, एआईडीएल, और RenderScript के लिए सहायता शामिल नहीं है.

  • डिफ़ॉल्ट रूप से बंद टेस्ट: बिल्ड की स्पीड को बेहतर बनाने के लिए, यूनिट और डिवाइस (इंस्ट्रुमेंटेशन), दोनों टेस्ट डिफ़ॉल्ट रूप से बंद होते हैं. अगर ज़रूरी हो, तो इन्हें चालू किया जा सकता है.

  • कोई टॉप-लेवल Android एक्सटेंशन नहीं: कॉन्फ़िगरेशन को Gradle KMP DSL में मौजूद androidLibrary ब्लॉक से मैनेज किया जाता है. इससे KMP प्रोजेक्ट का स्ट्रक्चर एक जैसा बना रहता है. android के टॉप-लेवल एक्सटेंशन पर कोई रोक नहीं है.

  • Java कंपाइलेशन के लिए ऑप्ट-इन करना: Java कंपाइलेशन डिफ़ॉल्ट रूप से बंद होता है. इसे चालू करने के लिए, androidLibrary ब्लॉक में withJava() का इस्तेमाल करें. इससे Java कंपाइलेशन की ज़रूरत न होने पर, बिल्ड के समय में सुधार होता है.

Android-KMP लाइब्रेरी प्लगिन के फ़ायदे

Android-KMP प्लगिन, KMP प्रोजेक्ट के लिए ये फ़ायदे देता है:

  • बिल्ड की परफ़ॉर्मेंस और स्थिरता को बेहतर बनाया गया है: इसे KMP प्रोजेक्ट में, बिल्ड की स्पीड को ऑप्टिमाइज़ करने और स्थिरता को बेहतर बनाने के लिए डिज़ाइन किया गया है. KMP के वर्कफ़्लो पर फ़ोकस करने से, बिल्ड प्रोसेस ज़्यादा बेहतर और भरोसेमंद हो जाती है.

  • बेहतर आईडीई इंटिग्रेशन: यह KMP Android लाइब्रेरी के साथ काम करते समय, कोड को बेहतर तरीके से पूरा करने, नेविगेट करने, डीबग करने, और डेवलपर को बेहतर अनुभव देने की सुविधा देता है.

  • प्रोजेक्ट को आसानी से कॉन्फ़िगर करना: यह प्लगिन, KMP प्रोजेक्ट को आसानी से कॉन्फ़िगर करने में मदद करता है. इसके लिए, यह Android से जुड़ी जटिलताओं को दूर करता है. जैसे, बिल्ड वैरिएंट. इससे, बिल्ड फ़ाइलें ज़्यादा व्यवस्थित और रखरखाव में आसान हो जाती हैं. पहले, KMP प्रोजेक्ट में com.android.library प्लगिन का इस्तेमाल करने पर, source set के नाम गलत हो सकते थे. जैसे, androidAndroidTest. नाम रखने का यह तरीका, स्टैंडर्ड KMP प्रोजेक्ट स्ट्रक्चर के बारे में जानने वाले डेवलपर के लिए कम सहज था.

ज़रूरी शर्तें

com.android.kotlin.multiplatform.library प्लगिन का इस्तेमाल करने के लिए, आपके प्रोजेक्ट में कम से कम ये वर्शन या इससे ऊपर के वर्शन कॉन्फ़िगर होने चाहिए:

  • Android Gradle Plugin (AGP): 8.10.0
  • Kotlin Gradle Plugin (KGP): 2.0.0

किसी मौजूदा मॉड्यूल पर Android-KMP प्लगिन लागू करना

किसी मौजूदा KMP लाइब्रेरी मॉड्यूल पर Android-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 = "8.12.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 फ़ाइल खोलें. apply false का इस्तेमाल करके, प्लगिन के अन्य नाम plugins ब्लॉक में जोड़ें. इससे प्लगिन के दूसरे नाम, सभी सबप्रोजेक्ट के लिए उपलब्ध हो जाते हैं. इसके लिए, प्लगिन के लॉजिक को रूट प्रोजेक्ट पर लागू करने की ज़रूरत नहीं होती.

    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
    }

    Groovy

    // 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 लाइब्रेरी मॉड्यूल की बिल्ड फ़ाइल में प्लगिन लागू करें. अपने KMP लाइब्रेरी मॉड्यूल में build.gradle.kts फ़ाइल खोलें और plugins ब्लॉक में अपनी फ़ाइल के सबसे ऊपर प्लगिन लागू करें:

    Kotlin

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

    Groovy

    // Module-specific build.gradle file
    
    plugins {
       alias(libs.plugins.kotlin.multiplatform)
    
       // Add the following
       alias(libs.plugins.android.kotlin.multiplatform.library)
    }
  4. Android KMP टारगेट को कॉन्फ़िगर करें. Android टारगेट तय करने के लिए, Kotlin Multiplatform ब्लॉक (kotlin) को कॉन्फ़िगर करें. kotlin ब्लॉक में, androidLibrary का इस्तेमाल करके Android टारगेट तय करें:

    Kotlin

    kotlin {
       androidLibrary {
           namespace = "com.example.kmpfirstlib"
           compileSdk = 33
           minSdk = 24
    
           withJava() // enable java compilation support
           withHostTestBuilder {}.configure {}
           withDeviceTestBuilder {
               sourceSetTreeName = "test"
           }
    
           compilations.configureEach {
               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.) ...
    }

    Groovy

    kotlin {
       androidLibrary {
           namespace = "com.example.kmpfirstlib"
           compileSdk = 33
           minSdk = 24
    
           withJava() // enable java compilation support
           withHostTestBuilder {}.configure {}
           withDeviceTestBuilder {
               it.sourceSetTreeName = "test"
           }
    
           compilations.configureEach {
               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. डिपेंडेंसी का एलान करना

Android के लिए खास तौर पर बनाए गए सोर्स सेट के लिए डिपेंडेंसी का एलान करना, एक सामान्य टास्क है. नए प्लगिन के लिए, इन कोड को sourceSets ब्लॉक में साफ़ तौर पर रखना ज़रूरी है. हालांकि, पहले इस्तेमाल किए गए सामान्य dependencies ब्लॉक में ऐसा नहीं था.

Android-KMP

नया प्लगिन, Android डिपेंडेंसी को androidMain सोर्स सेट में ग्रुप करके, बेहतर स्ट्रक्चर को बढ़ावा देता है. मुख्य सोर्स सेट के अलावा, दो टेस्ट सोर्स सेट होते हैं. इन्हें मांग पर बनाया जाता है: 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 {
    androidLibrary {
        compilations.getByName("deviceTest") {
            kotlinOptions.languageVersion = "2.0"
        }
    }
}

लेगसी प्लगिन

पुराने प्लगिन में, टॉप-लेवल डिपेंडेंसी ब्लॉक में Android के लिए खास तौर पर बनाई गई डिपेंडेंसी का एलान किया जा सकता था. हालांकि, मल्टीप्लैटफ़ॉर्म मॉड्यूल में कभी-कभी यह भ्रम की स्थिति पैदा कर सकता था.

// 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")
}

2. Android के संसाधनों को चालू करना

बिल्ड की परफ़ॉर्मेंस को ऑप्टिमाइज़ करने के लिए, नए प्लगिन में Android Resources (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

लेगसी प्लगिन

संसाधन प्रोसेसिंग की सुविधा डिफ़ॉल्ट रूप से चालू थी. src/main में तुरंत res डायरेक्ट्री जोड़ी जा सकती है. इसके बाद, एक्सएमएल ड्रॉएबल, वैल्यू वगैरह जोड़ी जा सकती हैं.

// 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

3. होस्ट और डिवाइस के टेस्ट कॉन्फ़िगर करना

नए प्लगिन में एक अहम बदलाव यह है कि Android होस्ट-साइड (यूनिट) और डिवाइस-साइड (इंस्ट्रुमेंटेड) टेस्ट डिफ़ॉल्ट रूप से बंद होते हैं. टेस्ट सोर्स सेट और कॉन्फ़िगरेशन बनाने के लिए, आपको साफ़ तौर पर ऑप्ट-इन करना होगा. वहीं, पुराना प्लगिन इन्हें अपने-आप बना देता था.

इस ऑप्ट-इन मॉडल से यह पुष्टि करने में मदद मिलती है कि आपका प्रोजेक्ट छोटा रहे और इसमें सिर्फ़ वे बिल्ड लॉजिक और सोर्स सेट शामिल हों जिनका इस्तेमाल किया जा रहा है.

Android-KMP

नए प्लगिन में, kotlin.android ब्लॉक के अंदर टेस्ट चालू और कॉन्फ़िगर किए जाते हैं. इससे सेटअप ज़्यादा साफ़ तौर पर किया जा सकता है और इस्तेमाल नहीं किए गए टेस्ट कॉम्पोनेंट बनाने से बचा जा सकता है. test सोर्स सेट androidHostTest बन जाता है और androidTest, 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 = "ANDROIDX_TEST_ORCHESTRATOR"
    }
  }
}

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

लेगसी प्लगिन

com.android.library प्लगिन की मदद से, test और androidTest सोर्स सेट डिफ़ॉल्ट रूप से बनाए गए थे. android ब्लॉक में, उनके व्यवहार को कॉन्फ़िगर किया जाता है. इसके लिए, आम तौर पर 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 = "ANDROIDX_TEST_ORCHESTRATOR"
  }
}

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

4. Java सोर्स कंपाइलेशन चालू करना

अगर आपकी KMP लाइब्रेरी को Android टारगेट के लिए Java सोर्स कंपाइल करने की ज़रूरत है, तो आपको नए प्लगिन की मदद से इस सुविधा को साफ़ तौर पर चालू करना होगा. ध्यान दें कि इससे आपके प्रोजेक्ट में मौजूद Java फ़ाइलों के लिए कंपाइलेशन चालू होता है, न कि इसकी डिपेंडेंसी के लिए. Java और Kotlin कंपाइलर के JVM टारगेट वर्शन को सेट करने का तरीका भी बदल जाता है.

Android-KMP

आपको withJava() पर कॉल करके, Java कंपाइलेशन के लिए ऑप्ट-इन करना होगा. अब जेवीएम टारगेट को सीधे तौर पर kotlin { androidLibrary {} } ब्लॉक में कॉन्फ़िगर किया जाता है, ताकि सेटअप को ज़्यादा एक जैसा बनाया जा सके. यहां दी गई jvmTarget सेटिंग, Android टारगेट के लिए Kotlin और Java, दोनों के कंपाइलेशन पर लागू होती है.

// 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 कंपाइलेशन की सुविधा डिफ़ॉल्ट रूप से चालू थी. Java और Kotlin, दोनों सोर्स के लिए JVM टारगेट को 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"
    }
  }
}

5. androidComponents का इस्तेमाल करके, बिल्ड वैरिएंट के साथ इंटरैक्ट करना

androidComponents एक्सटेंशन अब भी प्रोग्राम के हिसाब से, बिल्ड आर्टफ़ैक्ट के साथ इंटरैक्ट करने के लिए उपलब्ध है. Variant एपीआई के ज़्यादातर फ़ंक्शन पहले की तरह ही काम करते हैं. हालांकि, 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 ->
    // ...
  }
}

6. Android लाइब्रेरी डिपेंडेंसी के वैरिएंट चुनना

आपकी KMP लाइब्रेरी, Android के लिए एक ही वैरिएंट बनाती है. हालांकि, ऐसा हो सकता है कि आप किसी स्टैंडर्ड Android लाइब्रेरी (com.android.library) पर निर्भर हों, जिसके कई वैरिएंट हों. जैसे, free/paid प्रॉडक्ट के फ़्लेवर). यह एक सामान्य ज़रूरत है कि आपका प्रोजेक्ट, उस डिपेंडेंसी से किसी वैरिएंट को कैसे चुनता है.

Android-KMP

नया प्लगिन, इस लॉजिक को kotlin.android.localDependencySelection ब्लॉक में एक जगह पर इकट्ठा करता है और इसे साफ़ तौर पर दिखाता है. इससे यह साफ़ तौर पर पता चलता है कि बाहरी डिपेंडेंसी के कौनसे वैरिएंट, आपकी सिंगल-वैरिएंट 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"))
      }
    }
  }
}

लेगसी प्लगिन

आपने buildTypes and productFlavors ब्लॉक में, डिपेंडेंसी चुनने की रणनीतियां कॉन्फ़िगर की हैं. इसमें अक्सर, missingDimensionStrategy का इस्तेमाल करके, किसी ऐसे डाइमेंशन के लिए डिफ़ॉल्ट फ़्लेवर उपलब्ध कराना होता था जो आपकी लाइब्रेरी में मौजूद नहीं है. इसके अलावा, किसी फ़्लेवर में matchingFallbacks का इस्तेमाल करके, खोज का क्रम तय करना होता था.

एपीआई के इस्तेमाल के बारे में ज़्यादा जानकारी के लिए, मिलान से जुड़ी गड़बड़ियां ठीक करना लेख पढ़ें.

प्लगिन एपीआई का रेफ़रंस

नए प्लगिन का एपीआई, com.android.library से अलग है. नए डीएसएल और इंटरफ़ेस के बारे में ज़्यादा जानकारी के लिए, एपीआई के रेफ़रंस देखें: