Android बिल्ड में Java वर्शन

आपका सोर्स कोड Java, Kotlin या दोनों में लिखा गया हो, आपको अपने बिल्ड के लिए JDK या Java लैंग्वेज वर्शन को कई जगहों पर चुनना होगा.

Gradle बिल्ड में JDK के संबंधों की खास जानकारी
पहली इमेज. बिल्ड में JDK के संबंध

शब्दावली

Java डेवलपमेंट किट (JDK)
Java Development Kit (JDK) में ये शामिल हैं:
  • टूल, जैसे कि कंपाइलर, प्रोफ़ाइलर, और संग्रह बनाने वाला टूल. इनका इस्तेमाल, ऐप्लिकेशन बनाने के दौरान बैकग्राउंड में किया जाता है.
  • ऐसी लाइब्रेरी जिनमें एपीआई शामिल होते हैं. इन्हें अपने Kotlin या Java सोर्स कोड से कॉल किया जा सकता है. ध्यान दें कि Android पर सभी फ़ंक्शन उपलब्ध नहीं हैं.
  • Java वर्चुअल मशीन (JVM), एक इंटरप्रेटर है जो Java ऐप्लिकेशन को एक्ज़ीक्यूट करता है. Android Studio IDE और Gradle बिल्ड टूल को चलाने के लिए, JVM का इस्तेमाल किया जाता है. JVM का इस्तेमाल Android डिवाइसों या एम्युलेटर पर नहीं किया जाता.
JetBrains Runtime (JBR)
JetBrains Runtime (JBR) एक बेहतर JDK है. इसे Android Studio के साथ डिस्ट्रिब्यूट किया जाता है. इसमें Studio और JetBrains के अन्य प्रॉडक्ट में इस्तेमाल करने के लिए, कई ऑप्टिमाइज़ेशन शामिल हैं. हालाँकि, इसका इस्तेमाल अन्य Java ऐप्लिकेशन चलाने के लिए भी किया जा सकता है.

Android Studio चलाने के लिए, मैं JDK कैसे चुनूं?

हमारा सुझाव है कि Android Studio को चलाने के लिए, JBR का इस्तेमाल करें. इसे Android Studio के साथ डिप्लॉय किया जाता है और इसका इस्तेमाल Android Studio की जांच करने के लिए किया जाता है. साथ ही, इसमें Android Studio का बेहतर तरीके से इस्तेमाल करने के लिए कई सुधार किए गए हैं. यह पक्का करने के लिए, STUDIO_JDK एनवायरमेंट वैरिएबल सेट न करें.

Android Studio के लिए स्टार्टअप स्क्रिप्ट, इस क्रम में JVM ढूंढती हैं:

  1. STUDIO_JDK एनवायरमेंट वैरिएबल
  2. studio.jdk डायरेक्ट्री (Android Studio डिस्ट्रिब्यूशन में)
  3. Android Studio के डिस्ट्रिब्यूशन में, jbr डायरेक्ट्री (JetBrains Runtime) में मौजूद होता है. सुझाया गया.
  4. JDK_HOME एनवायरमेंट वैरिएबल
  5. JAVA_HOME एनवायरमेंट वैरिएबल
  6. java, PATH एनवायरमेंट वैरिएबल में मौजूद है

मैं कैसे चुनूं कि मेरे Gradle बिल्ड को कौनसा JDK चलाएगा?

Android Studio में मौजूद बटन का इस्तेमाल करके Gradle चलाने पर, Android Studio की सेटिंग में सेट किया गया JDK, Gradle को चलाने के लिए इस्तेमाल किया जाता है. अगर Gradle को Android Studio के अंदर या बाहर किसी टर्मिनल में चलाया जाता है, तो JAVA_HOME एनवायरमेंट वैरिएबल (अगर सेट है) यह तय करता है कि Gradle स्क्रिप्ट को कौनसे JDK से चलाया जाए. अगर JAVA_HOME सेट नहीं है, तो यह आपके PATH एनवायरमेंट वैरिएबल पर java कमांड का इस्तेमाल करता है.

सबसे सटीक नतीजे पाने के लिए, पक्का करें कि आपने JAVA_HOME एनवायरमेंट वैरिएबल और Android Studio में Gradle JDK कॉन्फ़िगरेशन को एक ही JDK पर सेट किया हो.

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

अगर अलग-अलग JDK या Gradle वर्शन के साथ बिल्ड शुरू किए जाते हैं, तो अतिरिक्त डेमॉन बनाए जाते हैं. इससे ज़्यादा सीपीयू और मेमोरी का इस्तेमाल होता है.

Android Studio में Gradle JDK कॉन्फ़िगरेशन

मौजूदा प्रोजेक्ट के Gradle JDK कॉन्फ़िगरेशन में बदलाव करने के लिए, फ़ाइल (या macOS पर Android Studio) > सेटिंग > बिल्ड, एक्ज़ीक्यूशन, डिप्लॉयमेंट > बिल्ड टूल > Gradle में जाकर, Gradle सेटिंग खोलें. Gradle JDK ड्रॉप-डाउन में, चुनने के लिए ये विकल्प होते हैं:

  • JAVA_HOME और GRADLE_LOCAL_JAVA_HOME जैसे मैक्रो
  • vendor-version फ़ॉर्मैट में JDK टेबल की एंट्री, जैसे कि jbr-17. इन्हें Android कॉन्फ़िगरेशन फ़ाइलों में सेव किया जाता है
  • JDK डाउनलोड करना
  • कोई खास JDK जोड़ना
  • ऑपरेटिंग सिस्टम के डिफ़ॉल्ट JDK इंस्टॉलेशन डायरेक्ट्री से स्थानीय तौर पर पता लगाए गए JDK

चुना गया विकल्प, प्रोजेक्ट की .idea/gradle.xml फ़ाइल में मौजूद gradleJvm विकल्प में सेव होता है. साथ ही, Android Studio से शुरू किए जाने पर Gradle को चलाने के लिए, इसके JDK पाथ रिज़ॉल्यूशन का इस्तेमाल किया जाता है.

दूसरी इमेज. Android Studio में Gradle JDK की सेटिंग.

मैक्रो की मदद से, प्रोजेक्ट के लिए JDK पाथ को डाइनैमिक तरीके से चुना जा सकता है:

  • JAVA_HOME: इसी नाम के एनवायरमेंट वैरिएबल का इस्तेमाल करता है
  • GRADLE_LOCAL_JAVA_HOME: यह .gradle/config.properties फ़ाइल में मौजूद java.home प्रॉपर्टी का इस्तेमाल करता है. इसकी डिफ़ॉल्ट वैल्यू JetBrains Runtime होती है.

चुने गए JDK का इस्तेमाल, Gradle बिल्ड को चलाने और JDK API के रेफ़रंस को हल करने के लिए किया जाता है. ऐसा तब किया जाता है, जब बिल्ड स्क्रिप्ट और सोर्स कोड में बदलाव किया जा रहा हो. ध्यान दें कि तय किए गए compileSdk से यह तय होगा कि सोर्स कोड में बदलाव करते समय और उसे बनाते समय, कौनसे Java सिंबल उपलब्ध होंगे.

पक्का करें कि आपने ऐसा JDK वर्शन चुना हो जो Gradle बिल्ड में इस्तेमाल किए जाने वाले प्लगिन के JDK वर्शन से ज़्यादा या उसके बराबर हो. Android Gradle प्लगिन (AGP) के लिए, ज़रूरी जेडीके का कम से कम वर्शन जानने के लिए, रिलीज़ नोट में दी गई कंपैटिबिलिटी टेबल देखें.

उदाहरण के लिए, Android Gradle प्लगिन 8.x के लिए JDK 17 की ज़रूरत होती है. अगर JDK के पुराने वर्शन के साथ इसका इस्तेमाल करने वाला Gradle बिल्ड चलाया जाता है, तो यह इस तरह का मैसेज दिखाता है:

An exception occurred applying plugin request [id: 'com.android.application']
> Failed to apply plugin 'com.android.internal.application'.
   > Android Gradle plugin requires Java 17 to run. You are currently using Java 11.
      Your current JDK is located in /usr/local/buildtools/java/jdk
      You can try some of the following options:
       - changing the IDE settings.
       - changing the JAVA_HOME environment variable.
       - changing `org.gradle.java.home` in `gradle.properties`.

मैं अपने Java या Kotlin सोर्स कोड में, कौनसे Java API इस्तेमाल कर सकता हूं?

Android ऐप्लिकेशन, JDK में तय किए गए कुछ एपीआई का इस्तेमाल कर सकता है. हालांकि, वह सभी एपीआई का इस्तेमाल नहीं कर सकता. Android SDK, उपलब्ध एपीआई के हिस्से के तौर पर, कई Java लाइब्रेरी फ़ंक्शन के इस्तेमाल के बारे में बताता है. compileSdk प्रॉपर्टी से यह तय होता है कि Kotlin या Java के सोर्स कोड को कंपाइल करते समय, Android SDK के किस वर्शन का इस्तेमाल किया जाए.

Kotlin

android {
    ...
    compileSdk = 36
}

शानदार

android {
    ...
    compileSdk 36
}

Android के हर वर्शन पर, JDK का कोई खास वर्शन और उसके उपलब्ध Java एपीआई का सबसेट काम करता है. अगर किसी ऐसे Java API का इस्तेमाल किया जाता है जो किसी ऐसे compileSdk में उपलब्ध है जो बताए गए minSdk में उपलब्ध नहीं है, तो हो सकता है कि Android के पुराने वर्शन में एपीआई का इस्तेमाल किया जा सके. इसके लिए, डीसुगरिंग नाम की प्रोसेस का इस्तेमाल किया जाता है. सपोर्ट किए गए एपीआई के लिए, डीसुगरिंग के ज़रिए उपलब्ध Java 11+ एपीआई देखें.

इस टेबल का इस्तेमाल करके यह पता लगाएं कि कौनसे Android API के साथ Java का कौनसा वर्शन काम करता है. साथ ही, यह भी जानें कि Java के कौनसे एपीआई उपलब्ध हैं.

Android Java एपीआई और भाषा से जुड़ी सुविधाएं
14 (एपीआई 34) 17 कोर लाइब्रेरी
13 (एपीआई 33) 11 कोर लाइब्रेरी
12 (एपीआई 32) 11 Java API
11 और इससे कम Android के वर्शन

मेरा Java सोर्स कोड कौनसे JDK से कंपाइल होता है?

Java टूलचेन JDK में, Java कंपाइलर होता है. इसका इस्तेमाल किसी भी Java सोर्स कोड को कंपाइल करने के लिए किया जाता है. यह JDK, बिल्ड के दौरान javadoc और यूनिट टेस्ट भी चलाता है.

टूलचेन डिफ़ॉल्ट रूप से, Gradle को चलाने के लिए इस्तेमाल किए गए JDK पर सेट होती है. डिफ़ॉल्ट सेटिंग का इस्तेमाल करने पर, अलग-अलग मशीनों पर बिल्ड चलाया जा सकता है. जैसे, आपकी लोकल मशीन और कोई अलग कंटीन्यूअस इंटिग्रेशन सर्वर. अगर अलग-अलग JDK वर्शन का इस्तेमाल किया जाता है, तो आपके बिल्ड के नतीजे अलग-अलग हो सकते हैं.

ज़्यादा भरोसेमंद बिल्ड बनाने के लिए, Java टूलचेन का वर्शन साफ़ तौर पर बताया जा सकता है. इसे तय करने पर:

  • यह बिल्ड चलाने वाले सिस्टम पर, JDK का पता लगाता है.
    • अगर कोई भी JDK मौजूद नहीं है और टूलचेन रिज़ॉल्वर तय किया गया है, तो उसे डाउनलोड करता है.
  • यह टूलचेन Java API को सोर्स कोड से कॉल करने के लिए उपलब्ध कराता है.
  • Java लैंग्वेज वर्शन का इस्तेमाल करके, Java सोर्स को कंपाइल करता है.
  • यह sourceCompatibility और targetCompatibility के लिए डिफ़ॉल्ट वैल्यू देता है.

हमारा सुझाव है कि आप हमेशा Java टूलचेन तय करें. साथ ही, यह पक्का करें कि तय किया गया JDK इंस्टॉल हो या अपनी बिल्ड में टूलचेन रिज़ॉल्वर जोड़ें.

आपके पास टूलचेन तय करने का विकल्प होता है. इससे यह तय किया जा सकता है कि आपका सोर्स कोड Java, Kotlin या दोनों में लिखा गया है. अपने मॉड्यूल के build.gradle(.kts) फ़ाइल के टॉप लेवल पर टूलचेन तय करें.

Java टूलचेन का वर्शन इस तरह तय करें:

Kotlin

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(17)
    }
}

शानदार

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(17)
    }
}

यह सुविधा, Kotlin, Java या दोनों के मिक्स सोर्स के लिए काम करती है.

टूलचेन JDK का वर्शन, Gradle को चलाने के लिए इस्तेमाल किए गए JDK के वर्शन के जैसा हो सकता है. हालांकि, ध्यान रखें कि इन दोनों का मकसद अलग-अलग होता है.

मैं अपने Java सोर्स कोड में, Java भाषा के सोर्स कोड की किन सुविधाओं का इस्तेमाल कर सकता/सकती हूँ?

sourceCompatibility प्रॉपर्टी से यह तय होता है कि Java सोर्स को कंपाइल करते समय, Java लैंग्वेज की कौनसी सुविधाएं उपलब्ध होंगी. इससे Kotlin सोर्स पर कोई असर नहीं पड़ता.

अपने मॉड्यूल की build.gradle(.kts) फ़ाइल में sourceCompatibility को इस तरह से तय करें:

Kotlin

android {
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_17
    }
}

शानदार

android {
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_17
    }
}

अगर इस प्रॉपर्टी की वैल्यू तय नहीं की जाती है, तो डिफ़ॉल्ट रूप से Java toolchain के वर्शन का इस्तेमाल किया जाता है. अगर Java टूलचेन का इस्तेमाल नहीं किया जा रहा है, तो यह Android Gradle प्लगिन के चुने गए वर्शन पर डिफ़ॉल्ट रूप से सेट हो जाता है. उदाहरण के लिए, Java 8 या इसके बाद का वर्शन.

Kotlin या Java सोर्स को कंपाइल करते समय, Java बाइनरी की किन सुविधाओं का इस्तेमाल किया जा सकता है?

targetCompatibility और jvmTarget प्रॉपर्टी से यह तय होता है कि कंपाइल किए गए Java और Kotlin सोर्स के लिए बाइटकोड जनरेट करते समय, Java क्लास-फ़ॉर्मैट के किस वर्शन का इस्तेमाल किया जाएगा.

Java में मिलती-जुलती सुविधाएं जोड़े जाने से पहले, Kotlin में कुछ सुविधाएं मौजूद थीं. शुरुआती Kotlin कंपाइलर को, Kotlin की उन सुविधाओं को दिखाने के लिए अपना तरीका बनाना पड़ा. इनमें से कुछ सुविधाओं को बाद में Java में जोड़ा गया. बाद के jvmTarget लेवल में, Kotlin कंपाइलर सीधे तौर पर Java की सुविधा का इस्तेमाल कर सकता है. इससे परफ़ॉर्मेंस बेहतर हो सकती है.

Android के अलग-अलग वर्शन पर, Java के अलग-अलग वर्शन काम करते हैं. targetCompatibility और jvmTarget को बढ़ाकर, Java की अतिरिक्त सुविधाओं का फ़ायदा लिया जा सकता है. हालांकि, ऐसा करने पर आपको Android SDK का कम से कम वर्शन भी बढ़ाना पड़ सकता है, ताकि यह सुविधा उपलब्ध हो.

ध्यान दें कि targetCompatibility की वैल्यू, sourceCompatibility से ज़्यादा या इसके बराबर होनी चाहिए. आम तौर पर, sourceCompatibility, targetCompatibility, और jvmTarget के लिए एक ही वैल्यू का इस्तेमाल किया जाना चाहिए. इन्हें इस तरह सेट किया जा सकता है:

Kotlin

android {
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_17
        targetCompatibility = JavaVersion.VERSION_17
    }
    kotlinOptions {
        jvmTarget = "17"
    }
}

शानदार

android {
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_17
        targetCompatibility JavaVersion.VERSION_17
    }
    kotlinOptions {
        jvmTarget '17'
    }
}

अगर इन प्रॉपर्टी के लिए कोई वैल्यू तय नहीं की जाती है, तो डिफ़ॉल्ट रूप से Java toolchain के वर्शन का इस्तेमाल किया जाता है. अगर Java टूलचेन का इस्तेमाल नहीं किया जा रहा है, तो डिफ़ॉल्ट वैल्यू अलग-अलग हो सकती हैं. इससे बिल्ड से जुड़ी समस्याएं हो सकती हैं. इसलिए, हमारा सुझाव है कि आप हमेशा इन वैल्यू को साफ़ तौर पर बताएं या Java टूलचेन का इस्तेमाल करें.