Gradle बिल्ड की खास जानकारी

आम तौर पर, Android ऐप्लिकेशन Gradle बिल्ड सिस्टम का इस्तेमाल करके बनाए जाते हैं. अपने बिल्ड को कॉन्फ़िगर करने के तरीके के बारे में जानकारी देने से पहले, हम बिल्ड के पीछे के कॉन्सेप्ट के बारे में बताएंगे, ताकि आप पूरे सिस्टम को देख सकें.

बिल्ड क्या है?

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

Tasks में ऐसे निर्देश शामिल होते हैं जो इनपुट को आउटपुट में बदलते हैं. प्लग इन, टास्क और उनके कॉन्फ़िगरेशन तय करते हैं. अपने बिल्ड में प्लग इन लागू करने से, उसके टास्क रजिस्टर हो जाते हैं. साथ ही, इनपुट और आउटपुट का इस्तेमाल करके, उन्हें एक साथ जोड़ दिया जाता है. उदाहरण के लिए, अपनी बिल्ड फ़ाइल में Android Gradle प्लग इन (AGP) लागू करने पर, APK या Android लाइब्रेरी बनाने के लिए ज़रूरी सभी टास्क रजिस्टर हो जाएंगे. java-library प्लग इन की मदद से, Java सोर्स कोड से jar बनाया जा सकता है. Kotlin और अन्य भाषाओं के लिए भी मिलते-जुलते प्लग इन मौजूद हैं. हालांकि, अन्य प्लग इन का मकसद प्लग इन को बेहतर बनाना है. उदाहरण के लिए, protobuf प्लग इन का मकसद, AGP या java-library जैसे मौजूदा प्लग इन में प्रोटोबबल की सुविधा जोड़ना है.

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

टास्क के इनपुट में फ़ाइलें और डायरेक्ट्री के साथ-साथ, ऐसी अन्य जानकारी भी शामिल हो सकती है जिसे Java टाइप (पूर्णांक, स्ट्रिंग या कस्टम क्लास) के तौर पर एन्कोड किया गया हो. आउटपुट सिर्फ़ डायरेक्ट्री या फ़ाइलें हो सकती हैं, क्योंकि उन्हें डिस्क पर लिखना होता है. किसी टास्क के आउटपुट को दूसरे टास्क के इनपुट से जोड़ने पर, दोनों टास्क एक-दूसरे से लिंक हो जाते हैं. इससे, एक टास्क को दूसरे से पहले चलाना पड़ता है.

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

Gradle बिल्ड चलने पर क्या होता है?

Gradle बिल्ड तीन चरणों में चलते हैं. इनमें से हर चरण, कोड के उन अलग-अलग हिस्सों को लागू करता है जिन्हें आपने अपनी बिल्ड फ़ाइलों में तय किया है.

  • शुरू करना यह तय करता है कि बिल्ड में कौनसे प्रोजेक्ट और सब-प्रोजेक्ट शामिल किए जाएं. साथ ही, यह आपकी बिल्ड फ़ाइलों और लागू किए गए प्लग इन वाले क्लासपाथ को सेट अप करता है. इस फ़ेज़ में, सेटिंग फ़ाइल पर फ़ोकस किया जाता है. इसमें, उन प्रोजेक्ट के बारे में बताया जाता है जिन्हें आपको बनाना है. साथ ही, उन जगहों के बारे में भी बताया जाता है जहां से प्लग इन और लाइब्रेरी फ़ेच करनी हैं.
  • कॉन्फ़िगरेशन, हर प्रोजेक्ट के लिए टास्क रजिस्टर करता है. साथ ही, उपयोगकर्ता के बिल्ड स्पेसिफ़िकेशन को लागू करने के लिए, बिल्ड फ़ाइल को चलाता है. यह समझना ज़रूरी है कि आपके कॉन्फ़िगरेशन कोड के पास, प्रोसेस के दौरान जनरेट हुए डेटा या फ़ाइलों का ऐक्सेस नहीं होगा.
  • एक्सीक्यूशन, आपके ऐप्लिकेशन को असल में "बिल्ड" करता है. कॉन्फ़िगरेशन का आउटपुट, टास्क का डायरेक्टेड ऐसाइक्लिक ग्राफ़ (डीएजी) होता है. इसमें, उपयोगकर्ता के अनुरोध पर किए जाने वाले सभी ज़रूरी बिल्ड चरणों को दिखाया जाता है. ये टास्क, कमांड लाइन पर दिए गए या बिल्ड फ़ाइलों में डिफ़ॉल्ट तौर पर मौजूद होते हैं. यह ग्राफ़, टास्क के बीच के संबंध को दिखाता है. यह संबंध, टास्क के एलान में साफ़ तौर पर दिया गया हो या उसके इनपुट और आउटपुट के आधार पर तय किया गया हो. अगर किसी टास्क का इनपुट, किसी दूसरे टास्क का आउटपुट है, तो उसे दूसरे टास्क के बाद चलाया जाना चाहिए. इस चरण में, ग्राफ़ में तय किए गए क्रम में पुराने टास्क चलाए जाते हैं. अगर किसी टास्क को आखिरी बार चलाए जाने के बाद उसके इनपुट में कोई बदलाव नहीं हुआ है, तो Gradle उसे छोड़ देगा.

ज़्यादा जानकारी के लिए, Gradle बिल्ड लाइफ़साइकल देखें.

कॉन्फ़िगरेशन डीएसएल

Gradle, बिल्ड को कॉन्फ़िगर करने के लिए डोमेन-स्पेसिफ़िक लैंग्वेज (DSL) का इस्तेमाल करता है. इस एनोटेशन वाले तरीके में, सिलसिलेवार (ज़रूरी) निर्देश लिखने के बजाय, आपके डेटा की जानकारी देने पर फ़ोकस किया जाता है. Kotlin या Groovy का इस्तेमाल करके, अपनी बिल्ड फ़ाइलें लिखी जा सकती हैं. हालांकि, हमारा सुझाव है कि आप Kotlin का इस्तेमाल करें.

डीएसएल की मदद से, डोमेन विशेषज्ञों और प्रोग्रामर के लिए किसी प्रोजेक्ट में योगदान देना आसान हो जाता है. इसके लिए, डीएसएल में एक छोटी भाषा तय की जाती है, जो डेटा को ज़्यादा आसान तरीके से दिखाती है. Gradle प्लग इन, अपने टास्क के लिए ज़रूरी डेटा को कॉन्फ़िगर करने के लिए, डीएसएल को बढ़ा सकते हैं.

उदाहरण के लिए, अपने बिल्ड के Android हिस्से को कॉन्फ़िगर करने का तरीका कुछ ऐसा दिख सकता है:

Kotlin

android {
    namespace = "com.example.app"
    compileSdk = 34
    // ...

    defaultConfig {
        applicationId = "com.example.app"
        minSdk = 34
        // ...
    }
}

Groovy

android {
    namespace 'com.example.myapplication'
    compileSdk 34
    // ...

    defaultConfig {
        applicationId "com.example.myapplication"
        minSdk 24
        // ...
    }
}

पर्दे के पीछे, डीएसएल कोड इस तरह का होता है:

fun Project.android(configure: ApplicationExtension.() -> Unit) {
    ...
}

interface ApplicationExtension {
    var compileSdk: Int
    var namespace: String?

    val defaultConfig: DefaultConfig

    fun defaultConfig(configure: DefaultConfig.() -> Unit) {
        ...
    }
}

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

बाहरी डिपेंडेंसी

Maven बिल्ड सिस्टम ने डिपेंडेंसी की खास जानकारी, स्टोरेज, और मैनेजमेंट सिस्टम को शामिल किया. लाइब्रेरी को रिपॉज़िटरी (सर्वर या डायरेक्ट्री) में सेव किया जाता है. इसमें मेटाडेटा भी शामिल होता है. जैसे, लाइब्रेरी का वर्शन और अन्य लाइब्रेरी पर निर्भरता. आपको यह तय करना होता है कि किन रिपॉज़िटरी को खोजना है और आपको किन डिपेंडेंसी के वर्शन का इस्तेमाल करना है. इसके बाद, बिल्ड सिस्टम बिल्ड के दौरान उन्हें डाउनलोड कर लेता है.

Maven आर्टफ़ैक्ट की पहचान, ग्रुप के नाम (कंपनी, डेवलपर वगैरह), आर्टफ़ैक्ट के नाम (लाइब्रेरी का नाम) और उस आर्टफ़ैक्ट के वर्शन से की जाती है. आम तौर पर, इसे group:artifact:version के तौर पर दिखाया जाता है.

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

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

हम बिल्ड डिपेंडेंसी जोड़ें में, डिपेंडेंसी तय करने के तरीके के बारे में ज़्यादा जानकारी देंगे.

वैरिएंट बनाना

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

बिल्ड टाइप के हिसाब से, बिल्ड के लिए तय किए गए विकल्प अलग-अलग होते हैं. डिफ़ॉल्ट रूप से, AGP "रिलीज़" और "डीबग" टाइप के बिल्ड सेट अप करता है. हालांकि, इनमें बदलाव किया जा सकता है और और भी टाइप जोड़े जा सकते हैं. जैसे, स्टैजिंग या इंटरनल टेस्टिंग के लिए.

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

रिलीज़ बिल्ड, ऐप्लिकेशन को ऑप्टिमाइज़ करता है, उसे आपकी रिलीज़ पासकोड से साइन करता है, और इंस्टॉल किए गए ऐप्लिकेशन की फ़ाइलों को सुरक्षित रखता है.

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

AGP, बिल्ड टाइप और प्रॉडक्ट फ़्लेवर के हर कॉम्बिनेशन के लिए वैरिएंट बनाता है. अगर आपने फ़्लेवर तय नहीं किए हैं, तो वैरिएंट के नाम, बिल्ड टाइप के हिसाब से तय किए जाते हैं. अगर आपने दोनों एट्रिब्यूट की वैल्यू दी है, तो वैरिएंट का नाम <flavor><Buildtype> होगा. उदाहरण के लिए, AGP, release और debug टाइप के बिल्ड और demo और full फ़्लेवर के साथ वैरिएंट बनाएगा:

  • demoRelease
  • demoDebug
  • fullRelease
  • fullDebug

अगले चरण

अब आपने बिल्ड के कॉन्सेप्ट देख लिए हैं. अब अपने प्रोजेक्ट में Android बिल्ड के स्ट्रक्चर पर नज़र डालें.