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 बिल्ड लाइफ़साइकल देखें.

कॉन्फ़िगरेशन DSL

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

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

उदाहरण के लिए, आपके बिल्ड के 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 के तौर पर दिखाया जाता है.

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

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

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

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

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

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

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

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

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

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

  • demoRelease
  • demoDebug
  • fullRelease
  • fullDebug

अगले चरण

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