टूल और लाइब्रेरी के बीच इंटरडिपेंडेंसी

बिल्ड डिपेंडेंसी, प्रोजेक्ट को बिल्ड करने के लिए ज़रूरी बाहरी कॉम्पोनेंट होते हैं. कोई बिल्ड, लाइब्रेरी, प्लग इन, सब-प्रोजेक्ट, Android SDK टूल, Kotlin और Java जैसे टूल, Android Studio जैसे डेवलपमेंट एनवायरमेंट, और Gradle पर निर्भर हो सकता है.

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

आम तौर पर, इससे कोई समस्या नहीं होती, क्योंकि कई लाइब्रेरी सेमांटिक वर्शनिंग नाम की स्कीम का इस्तेमाल करती हैं. ये लाइब्रेरी, अपने पुराने वर्शन के साथ काम करने के लिए, कुछ तरह के बदलाव ही करती हैं.

सिमेंटिक वर्शन, major.minor.patch फ़ॉर्मैट का इस्तेमाल करता है. उदाहरण के लिए, वर्शन नंबर 4.8.3 में, 4 major वर्शन है, 8 minor वर्शन है, और 3 patch नंबर है. major वाला हिस्सा बदलने पर, लाइब्रेरी में एपीआई या उसके व्यवहार में काफ़ी बदलाव हो सकते हैं. इससे आपके बिल्ड या ऐप्लिकेशन के व्यवहार पर असर पड़ सकता है.

जब minor (नई सुविधाएं) या patch (बग ठीक करना) वाले हिस्से बदलते हैं, तो लाइब्रेरी के डेवलपर आपको बता रहे हैं कि लाइब्रेरी अब भी काम करती है और इससे आपके ऐप्लिकेशन पर कोई असर नहीं पड़ेगा.

ऐसे बदलावों पर नज़र रखना ज़रूरी है. डिपेंडेंसी अपग्रेड करने वाले कई टूल से आपको इसमें मदद मिल सकती है.

आपके बिल्ड में संबंध

Android बिल्ड में इनके बीच संबंध होते हैं:

  • सोर्स कोड - वह कोड और संसाधन जिन पर आपका कंट्रोल है
  • लाइब्रेरी डिपेंडेंसी - बाहरी लाइब्रेरी या मॉड्यूल, जिन्हें आपके प्रोजेक्ट और सब-प्रोजेक्ट में शामिल किया जाता है
  • टूल - कंपाइलर, प्लग इन, और SDK टूल, जो आपके सोर्स को ऐप्लिकेशन या लाइब्रेरी में बदलते हैं
डिपेंडेंसी और उनके रिलेशनशिप बनाना
पहली इमेज. संबंध बनाना

सोर्स कोड

आपका सोर्स कोड, Kotlin या Java कोड होता है. इसे आप अपने ऐप्लिकेशन या लाइब्रेरी में लिखते हैं. (C++ का इस्तेमाल करने के बारे में ज़्यादा जानकारी के लिए, Android NDK देखें.)

सोर्स कोड, लाइब्रेरी (इनमें Kotlin और Java रनटाइम लाइब्रेरी शामिल हैं) और Android SDK टूल पर निर्भर करता है. साथ ही, इसके लिए Kotlin या Java कंपाइलर की ज़रूरत होती है.

कुछ सोर्स कोड में ऐसे एनोटेशन शामिल होते हैं जिन्हें अतिरिक्त प्रोसेसिंग की ज़रूरत होती है. उदाहरण के लिए, अगर Jetpack Compose कोड लिखा जा रहा है, तो @Composable जैसे एनोटेशन जोड़े जाते हैं. इन्हें Compose Kotlin कंपाइलर प्लग इन से प्रोसेस करना होता है. अन्य एनोटेशन को Kotlin सिंबल प्रोसेसर (केएसपी) या एनोटेशन प्रोसेस करने वाले अलग-अलग टूल से प्रोसेस किया जा सकता है.

लाइब्रेरी डिपेंडेंसी

लाइब्रेरी में, आपके ऐप्लिकेशन के हिस्से के तौर पर खींचा गया बाइटकोड होता है. यह आपके बिल्ड में, एक Java JAR, Android लाइब्रेरी (AAR) या सब-प्रोजेक्ट हो सकता है. कई लाइब्रेरी, सेमेंटिक वर्शनिंग का इस्तेमाल करती हैं. इससे आपको यह समझने में मदद मिलती है कि अपग्रेड करने पर वे काम करती हैं या नहीं.

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

कभी-कभी किसी लाइब्रेरी को रनटाइम (minSdk) या कंपाइल करने के समय (compileSdk) Android SDK टूल के कम से कम वर्शन की ज़रूरत पड़ सकती है. ऐसा तब ज़रूरी होता है, जब कोई लाइब्रेरी Android SDK टूल या इसके दिए गए JDK API में शामिल फ़ंक्शन का इस्तेमाल करती है. आपके ऐप्लिकेशन का minSdk असरदार है, जो आपके ऐप्लिकेशन और इसकी सभी डायरेक्ट और ट्रांज़िटिव लाइब्रेरी डिपेंडेंसी के लिए अनुरोध किया गया सबसे ज़्यादा minSdk है.

कुछ लाइब्रेरी का इस्तेमाल करने के लिए, आपको किसी खास Gradle प्लग इन का इस्तेमाल करना पड़ सकता है. ये हेल्पर प्लग इन, अक्सर Kotlin सिंबल प्रोसेसर या अन्य एनोटेशन प्रोसेसर इंस्टॉल करते हैं. ये प्रोसेसर, कोड जनरेट करते हैं या लाइब्रेरी की सुविधाओं का इस्तेमाल करने के लिए, आपके सोर्स के कंपाइलेशन में बदलाव करते हैं. उदाहरण के लिए, Jetpack Room में एनोटेशन और एक KSP शामिल है, जो उन्हें डेटाबेस में डेटा पाने और उसमें बदलाव करने के लिए जनरेट किए गए कोड में बदल देता है. Jetpack Compose के लिए, Compose कंपाइलर प्लग इन की ज़रूरत होती है, ताकि एनोटेट किए गए फ़ंक्शन में बदलाव किया जा सके. इससे यह मैनेज किया जा सकता है कि फ़ंक्शन को फिर से कब और कैसे चलाया जाए.

टूल

ग्रेडल

Gradle एक बिल्ड टूल है, जो आपकी बिल्ड फ़ाइलों को पढ़ता है और आपके ऐप्लिकेशन या लाइब्रेरी को जनरेट करता है. साथ ही, यह प्लगिन के लिए एपीआई उपलब्ध कराता है, ताकि वे अपनी क्षमताओं को बढ़ा सकें. Gradle, एक या उससे ज़्यादा Java वर्चुअल मशीन पर कई प्रोसेस चलाता है. साथ ही, इसके Java प्लग इन, JDK में मौजूद Java टूल को कॉल करते हैं.

Gradle प्लग इन

Gradle प्लग इन, नए टास्क और कॉन्फ़िगरेशन तय करके Gradle को बढ़ाते हैं. बिल्ड में प्लगिन लागू करने से, बिल्ड की खास क्षमताएं चालू हो जाती हैं. इन्हें आपकी बिल्ड स्क्रिप्ट में डेटा के तौर पर कॉन्फ़िगर किया जाता है. Android बिल्ड के लिए, Android Gradle प्लग इन (AGP) सबसे ज़रूरी Gradle प्लग इन है.

संकलनकर्ता

Kotlin या Java कंपाइलर, आपके सोर्स कोड को एक्ज़ीक्यूटेबल बाइटकोड में बदल देता है. Kotlin कंपाइलर, एक प्लग इन एपीआई को एक्सपोज़ करता है. इसकी मदद से, बाहरी विश्लेषण और कोड जनरेशन को सीधे कंपाइलर में चलाया जा सकता है. इसके लिए, पार्स किए गए कोड स्ट्रक्चर को ऐक्सेस किया जाता है.

कंपाइलर प्लग इन

कंपाइलर प्लग इन, Kotlin कंपाइलर के अंदर विश्लेषण और कोड जनरेशन करते हैं. ऐसा तब होता है, जब Kotlin कंपाइलर आपके कोड का विश्लेषण कर रहा हो. साथ ही, ये प्लग इन तब इंस्टॉल होते हैं, जब बिल्ड में उनके Gradle प्लग इन लागू किए जाते हैं.

Android SDK

Android SDK टूल में, Android के किसी खास वर्शन के लिए Android प्लैटफ़ॉर्म और Java API के साथ-साथ, उससे जुड़े टूल शामिल होते हैं. इन टूल की मदद से, SDK टूल को मैनेज किया जा सकता है, ऐप्लिकेशन बनाए जा सकते हैं, और Android डिवाइसों से संपर्क किया जा सकता है. साथ ही, इनकी मदद से Android डिवाइसों को एमुलेट भी किया जा सकता है.

Android SDK का हर वर्शन खास Java API उपलब्ध कराता है, जिन्हें आपका सोर्स कोड ऐक्सेस कर सकता है. साथ ही, यह Android के पुराने वर्शन पर उन एपीआई के इस्तेमाल के लिए ज़रूरत के मुताबिक काम करता है.

JDK

Java डेवलपमेंट किट, जिसमें Java लाइब्रेरी और Java सोर्स को कंपाइल करने और Java ऐप्लिकेशन चलाने के लिए, एक्ज़ीक्यूटेबल शामिल होते हैं. Android बिल्ड में कई JDK काम करते हैं. ज़्यादा जानकारी के लिए, Android बिल्ड में Java वर्शन देखें.

Gradle स्कोप

Gradle, लाइब्रेरी डिपेंडेंसी को अलग-अलग स्कोप में ग्रुप करता है. इन्हें Gradle API में कॉन्फ़िगरेशन कहा जाता है. इससे, आपको लाइब्रेरी डिपेंडेंसी के अलग-अलग सेट तय करने में मदद मिलती है, ताकि उनका इस्तेमाल आपके बिल्ड के अलग-अलग हिस्सों में किया जा सके. उदाहरण के लिए, हो सकता है कि आप अपने पब्लिश किए गए ऐप्लिकेशन या लाइब्रेरी में, JUnit जैसी टेस्ट लाइब्रेरी शामिल न करना चाहें. हालांकि, यूनिट टेस्ट बनाने और उन्हें लागू करने के दौरान, आपको इन लाइब्रेरी की ज़रूरत पड़ सकती है. अपने कोड का विश्लेषण करने के लिए, स्कोप का इस्तेमाल करके सिंबल या एनोटेशन प्रोसेसर भी जोड़े जा सकते हैं.

उदाहरण के लिए, AGP में implementation और api स्कोप शामिल किए गए हैं. इनसे यह तय किया जा सकता है कि आपके सब-प्रोजेक्ट के उपयोगकर्ताओं को कोई डिपेंडेंसी दिखनी चाहिए या नहीं. Android बिल्ड में इस्तेमाल किए गए इन और अन्य स्कोप के ब्यौरे के लिए, डिपेंडेंसी कॉन्फ़िगर करना देखें.

अपनी बिल्ड फ़ाइलों के dependencies ब्लॉक में, लाइब्रेरी डिपेंडेंसी जोड़ें. ऐसा या तो group:artifact:version स्ट्रिंग के तौर पर करें:

Kotlin

// In a module-level build script
// explicit dependency strings ("group:artifact:version")
dependencies {
    implementation("com.example:library1:1.2.3")
    api("com.example:library2:1.1.1")
}

Groovy

// In a module-level build script
// explicit dependency strings ("group:artifact:version")
dependencies {
    implementation 'com.example:library1:1.2.3'
    api 'com.example:library2:1.1.1'
}

या वर्शन कैटलॉग में:

# Version catalog - gradle/libs.versions.toml
[versions]
exampleLib = "1.2.3"
examplePlugin = "2.3.4"

[libraries]
example-library = { group = "com.example", name = "library", version.ref = "exampleLib" }

[plugins]
example-plugin = { id = "com.example.plugin", version.ref = "examplePlugin" }

और अपनी बिल्ड फ़ाइलों में जनरेट किए गए वैरिएबल की जानकारी दें:

Kotlin

// In a module-level build script
// Using a version catalog
plugins {
    alias(libs.plugins.example.plugin)
}

dependencies {
    implementation(libs.example.library)
}

Groovy

// In a module-level build script
// Using a version catalog
plugins {
    alias(libs.plugins.example.plugin)
}

dependencies {
    implementation libs.example.library
}