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

बिल्ड डिपेंडेंसी, प्रोजेक्ट को बिल्ड करने के लिए ज़रूरी बाहरी कॉम्पोनेंट होते हैं. कोई बिल्ड, लाइब्रेरी, प्लग इन, सब-प्रोजेक्ट, 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 एक बिल्ड टूल है, जो आपकी बिल्ड फ़ाइलों को पढ़ता है और आपका ऐप्लिकेशन या लाइब्रेरी जनरेट करता है. साथ ही, प्लग इन के लिए एपीआई भी उपलब्ध कराता है, ताकि उनकी सुविधाओं को बढ़ाया जा सके. 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
}