Android के लिए, तेज़ी से इटरेटिव डेवलपमेंट करना
इस पेज पर बताया गया है कि bazel mobile-install
, Android के लिए बार-बार डेवलपमेंट करने की प्रोसेस को कैसे ज़्यादा तेज़ बनाता है. इसमें, अलग-अलग बिल्ड और इंस्टॉल करने के चरणों की कमियों के मुकाबले, इस तरीके के फ़ायदों के बारे में बताया गया है.
खास जानकारी
Android ऐप्लिकेशन में छोटे-मोटे बदलावों को तुरंत इंस्टॉल करने के लिए, यह तरीका अपनाएं:
- उस ऐप्लिकेशन का
android_binary
नियम ढूंढें जिसे आपको इंस्टॉल करना है. - अपने डिवाइस को
adb
से कनेक्ट करें. bazel mobile-install :your_target
रन करें. ऐप्लिकेशन को चालू होने में सामान्य से थोड़ा ज़्यादा समय लगेगा.- कोड या Android संसाधनों में बदलाव करें.
bazel mobile-install :your_target
रन करें.- तेज़ी से और कम समय में इंक्रीमेंटल इंस्टॉलेशन का आनंद लें!
Bazel के लिए कुछ कमांड-लाइन विकल्प, जो आपके काम आ सकते हैं:
--adb
से Bazel को पता चलता है कि किस adb बाइनरी का इस्तेमाल करना है--adb_arg
का इस्तेमाल,adb
की कमांड लाइन में अतिरिक्त आर्ग्युमेंट जोड़ने के लिए किया जा सकता है. इसका एक फ़ायदेमंद इस्तेमाल यह है कि अगर आपके वर्कस्टेशन से एक से ज़्यादा डिवाइस कनेक्ट हैं, तो यह चुना जा सकता है कि आपको किस डिवाइस पर इंस्टॉल करना है:bazel mobile-install :your_target -- --adb_arg=-s --adb_arg=<SERIAL>
अगर आपको कोई समस्या आ रही है, तो उदाहरण देखें, Google Groups पर हमसे संपर्क करें या GitHub पर समस्या की शिकायत करें
परिचय
डेवलपर के टूलचेन की सबसे अहम विशेषताओं में से एक है स्पीड: कोड में बदलाव करने और उसे एक सेकंड के अंदर चलते हुए देखने में बहुत अंतर होता है. इसके अलावा, इस बात का फ़ीडबैक पाने के लिए कि आपके बदलाव आपकी उम्मीद के मुताबिक काम कर रहे हैं या नहीं, आपको मिनटों या कभी-कभी घंटों तक इंतज़ार करना पड़ता है.
माफ़ करें, .apk बनाने के लिए Android की पारंपरिक टूलचेन में कई मोनोलिथिक और क्रमवार चरण शामिल होते हैं. Android ऐप्लिकेशन बनाने के लिए, इन सभी चरणों को पूरा करना ज़रूरी होता है. Google में, Google Maps जैसे बड़े प्रोजेक्ट में एक लाइन के बदलाव को बनाने के लिए पांच मिनट इंतज़ार करना सामान्य बात थी.
bazel mobile-install
, Android के लिए बार-बार डेवलपमेंट करने की प्रोसेस को बहुत तेज़ बना देता है. इसके लिए, यह बदलावों को कम करने, काम को बांटने, और Android के इंटरनल को स्मार्ट तरीके से मैनेज करने की तकनीकों का इस्तेमाल करता है. इन सभी तकनीकों का इस्तेमाल, आपके ऐप्लिकेशन के कोड में कोई बदलाव किए बिना किया जाता है.
ऐप्लिकेशन को पारंपरिक तरीके से इंस्टॉल करने में आने वाली समस्याएं
Android ऐप्लिकेशन बनाने में कुछ समस्याएं आती हैं. जैसे:
Dexing. डिफ़ॉल्ट रूप से, बिल्ड में Dexer टूल (पहले
dx
, अबd8
याr8
) को सिर्फ़ एक बार चालू किया जाता है. इसे यह नहीं पता होता कि पिछले बिल्ड के काम को कैसे रीयूज़ किया जाए: यह हर तरीके को फिर से डेक्स करता है, भले ही सिर्फ़ एक तरीका बदला गया हो.डिवाइस पर डेटा अपलोड किया जा रहा है. adb, यूएसबी 2.0 कनेक्शन के पूरे बैंडविड्थ का इस्तेमाल नहीं करता है. इसलिए, बड़े ऐप्लिकेशन को अपलोड होने में ज़्यादा समय लग सकता है. पूरे ऐप्लिकेशन को अपलोड किया जाता है. भले ही, सिर्फ़ छोटे-छोटे हिस्सों में बदलाव किया गया हो. उदाहरण के लिए, कोई संसाधन या एक तरीका. इसलिए, यह एक बड़ी समस्या हो सकती है.
नेटिव कोड में कंपाइल करना. Android L में ART को पेश किया गया था. यह एक नया Android रनटाइम है. यह ऐप्लिकेशन को Dalvik की तरह, ऐप्लिकेशन इस्तेमाल करने के दौरान कंपाइल करने के बजाय, पहले से ही कंपाइल कर देता है. इससे ऐप्लिकेशन बहुत तेज़ी से काम करते हैं. हालांकि, इन्हें इंस्टॉल करने में ज़्यादा समय लगता है. यह उपयोगकर्ताओं के लिए एक अच्छा समझौता है, क्योंकि वे आम तौर पर किसी ऐप्लिकेशन को एक बार इंस्टॉल करते हैं और उसे कई बार इस्तेमाल करते हैं. हालांकि, इससे ऐप्लिकेशन को डेवलप करने में ज़्यादा समय लगता है. ऐसा तब होता है, जब किसी ऐप्लिकेशन को कई बार इंस्टॉल किया जाता है और हर वर्शन को ज़्यादा से ज़्यादा कुछ बार चलाया जाता है.
bazel mobile-install
का अप्रोच
bazel mobile-install
में ये सुधार किए गए हैं:
शार्ड किए गए डीसुगरिंग और डेक्सिंग. ऐप्लिकेशन का Java कोड बनाने के बाद, Bazel क्लास फ़ाइलों को लगभग बराबर साइज़ वाले हिस्सों में बांट देता है. इसके बाद, वह उन पर
d8
को अलग-अलग तरीके से लागू करता है.d8
को उन शार्ड पर लागू नहीं किया जाता जिनमें पिछले बिल्ड के बाद से कोई बदलाव नहीं हुआ है. इसके बाद, इन शार्ड को अलग-अलग शार्ड किए गए APK में कंपाइल किया जाता है.इंक्रीमेंटल फ़ाइल ट्रांसफ़र. Android के संसाधनों, .dex फ़ाइलों, और नेटिव लाइब्रेरी को मुख्य .apk से हटा दिया जाता है. इन्हें मोबाइल-इंस्टॉल डायरेक्ट्री में सेव किया जाता है. इससे पूरे ऐप्लिकेशन को फिर से इंस्टॉल किए बिना, कोड और Android संसाधनों को अलग-अलग अपडेट किया जा सकता है. इसलिए, फ़ाइलों को ट्रांसफ़र करने में कम समय लगता है. साथ ही, डिवाइस पर सिर्फ़ उन .dex फ़ाइलों को फिर से कंपाइल किया जाता है जिनमें बदलाव किया गया है.
शार्ड किया गया इंस्टॉलेशन. मोबाइल-इंस्टॉल, कनेक्ट किए गए डिवाइस पर शार्ड किए गए APK को एक साथ लाने के लिए, Android Studio के
apkdeployer
टूल का इस्तेमाल करता है. इससे आपको एक जैसा अनुभव मिलता है.
शार्ड किया गया डेक्सिंग
शार्ड की गई डेक्सिंग का तरीका काफ़ी आसान है: .jar फ़ाइलें बनने के बाद, टूल उन्हें लगभग एक ही साइज़ की अलग-अलग .jar फ़ाइलों में शार्ड करता है. इसके बाद, उन फ़ाइलों पर d8
को लागू करता है जिनमें पिछली बिल्ड के बाद बदलाव किए गए हैं. यह तय करने का लॉजिक कि किन शार्ड को डेक्स करना है, Android के लिए खास नहीं है. यह सिर्फ़ Bazel के सामान्य बदलावों को हटाने वाले एल्गोरिदम का इस्तेमाल करता है.
शार्डिंग एल्गोरिदम के पहले वर्शन में, .class फ़ाइलों को वर्णमाला के क्रम में लगाया जाता था. इसके बाद, सूची को बराबर साइज़ के हिस्सों में काट दिया जाता था. हालांकि, यह तरीका सही नहीं था. अगर कोई क्लास जोड़ी या हटाई जाती थी (भले ही, वह नेस्ट की गई हो या गुमनाम हो), तो वर्णमाला के क्रम में उसके बाद आने वाली सभी क्लास एक से शिफ़्ट हो जाती थीं. इससे उन शार्ड को फिर से डेक्स करना पड़ता था. इसलिए, अलग-अलग क्लास के बजाय Java पैकेज को शार्ड करने का फ़ैसला लिया गया. निश्चित तौर पर, अगर कोई नया पैकेज जोड़ा या हटाया जाता है, तो इससे कई शार्ड इंडेक्स हो जाते हैं. हालांकि, ऐसा किसी एक क्लास को जोड़ने या हटाने की तुलना में बहुत कम होता है.
शार्ड की संख्या को कमांड-लाइन कॉन्फ़िगरेशन से कंट्रोल किया जाता है. इसके लिए, --define=num_dex_shards=N
फ़्लैग का इस्तेमाल किया जाता है. आदर्श रूप से, Bazel अपने-आप यह तय कर लेता है कि कितने शार्ड सबसे सही हैं. हालांकि, Bazel को फ़िलहाल किसी भी कार्रवाई को पूरा करने से पहले, कार्रवाइयों के सेट के बारे में पता होना चाहिए. उदाहरण के लिए, बिल्ड के दौरान एक्ज़ीक्यूट किए जाने वाले कमांड. इसलिए, यह शार्ड की सबसे सही संख्या का पता नहीं लगा सकता, क्योंकि इसे यह नहीं पता कि ऐप्लिकेशन में आखिर में कितनी Java क्लास होंगी. आम तौर पर, जितने ज़्यादा शार्ड होंगे, बिल्ड और इंस्टॉलेशन उतना ही तेज़ होगा. हालांकि, इससे ऐप्लिकेशन के शुरू होने में उतना ही ज़्यादा समय लगेगा, क्योंकि डाइनैमिक लिंकर को ज़्यादा काम करना होगा. आम तौर पर, 10 से 50 शार्ड के बीच का डेटा सबसे अच्छा होता है.
इंक्रीमेंटल डिप्लॉयमेंट
अब इंक्रीमेंटल एपीके शार्ड को ट्रांसफ़र और इंस्टॉल करने का काम, apkdeployer
यूटिलिटी करती है. इसके बारे में "मोबाइल-इंस्टॉल का तरीका" में बताया गया है.
मोबाइल ऐप्लिकेशन इंस्टॉल करने के लिए, पहले (नेटिव) वर्शन में पहली बार इंस्टॉल करने वाले लोगों को मैन्युअल तरीके से ट्रैक करना पड़ता था. साथ ही, बाद में इंस्टॉल करने वाले लोगों के लिए --incremental
फ़्लैग को चुनिंदा तौर पर लागू करना पड़ता था. हालांकि, rules_android
के सबसे नए वर्शन में, इस प्रोसेस को काफ़ी आसान बना दिया गया है. मोबाइल ऐप्लिकेशन इंस्टॉल करने के लिए, एक ही इनवोकेशन का इस्तेमाल किया जा सकता है. इससे कोई फ़र्क़ नहीं पड़ता कि ऐप्लिकेशन को कितनी बार इंस्टॉल या फिर से इंस्टॉल किया गया है.
apkdeployer
टूल, adb
के अलग-अलग सब-कमांड के लिए रैपर का काम करता है. मुख्य एंट्रीपॉइंट लॉजिक, com.android.tools.deployer.Deployer
क्लास में मौजूद होता है. साथ ही, अन्य यूटिलिटी क्लास एक ही पैकेज में मौजूद होती हैं.
Deployer
क्लास, अन्य चीज़ों के साथ-साथ, स्प्लिट किए गए APK के पाथ की सूची और इंस्टॉलेशन के बारे में जानकारी देने वाला प्रोटोबफ़र भी लेता है. साथ ही, इंस्टॉल सेशन बनाने और ऐप्लिकेशन स्प्लिट को धीरे-धीरे डिप्लॉय करने के लिए, Android ऐप्लिकेशन बंडल के लिए डिप्लॉयमेंट की सुविधाओं का इस्तेमाल करता है.
लागू करने से जुड़ी जानकारी के लिए, ApkPreInstaller
और ApkInstaller
क्लास देखें.
नतीजे
परफ़ॉर्मेंस
आम तौर पर, bazel mobile-install
की वजह से, छोटे बदलाव के बाद बड़े ऐप्लिकेशन को बनाने और इंस्टॉल करने की प्रोसेस 4 से 10 गुना तेज़ हो जाती है.
यहां दिए गए नंबर, Google के कुछ प्रॉडक्ट के लिए कैलकुलेट किए गए हैं:
हालांकि, यह बदलाव के टाइप पर निर्भर करता है. जैसे, बेस लाइब्रेरी में बदलाव करने के बाद फिर से कंपाइल करने में ज़्यादा समय लगता है.
सीमाएं
स्टब ऐप्लिकेशन की ट्रिक्स, हर मामले में काम नहीं करती हैं. यहां कुछ ऐसे उदाहरण दिए गए हैं जिनमें यह सुविधा उम्मीद के मुताबिक काम नहीं करती:
मोबाइल ऐप्लिकेशन इंस्टॉल करने के लिए, सिर्फ़
rules_android
के Starlark नियमों का इस्तेमाल किया जा सकता है. ज़्यादा जानकारी के लिए, "मोबाइल ऐप्लिकेशन इंस्टॉल करने से जुड़ी जानकारी" देखें.यह सुविधा सिर्फ़ ART पर काम करने वाले डिवाइसों पर उपलब्ध है. मोबाइल ऐप्लिकेशन इंस्टॉल करने के लिए, एपीआई और रनटाइम सुविधाओं का इस्तेमाल किया जाता है. ये सुविधाएं सिर्फ़ ART पर काम करने वाले डिवाइसों पर उपलब्ध होती हैं, Dalvik पर नहीं. Android L (एपीआई 21+) से ज़्यादा नए Android रनटाइम के साथ काम करना चाहिए.
Bazel को Java रनटाइम और भाषा के 17 या इसके बाद के वर्शन वाले टूल के साथ चलाया जाना चाहिए.
Bazel के 8.4.0 से पहले के वर्शन में, मोबाइल-इंस्टॉल के लिए कुछ अतिरिक्त फ़्लैग तय करने होंगे. Bazel Android ट्यूटोरियल देखें. इन फ़्लैग से Bazel को पता चलता है कि Starlark मोबाइल-इंस्टॉल पहलू कहां है और कौनसे नियमों का इस्तेमाल किया जा सकता है.
मोबाइल ऐप्लिकेशन इंस्टॉल करने की सुविधा के बारे में खास जानकारी
Bazel के पुराने वर्शन में, C++, Java, और Android जैसी लोकप्रिय भाषाओं और इकोसिस्टम के लिए, बिल्ड और टेस्ट के नियम पहले से मौजूद होते थे. इसलिए, इन नियमों को नेटिव नियम कहा जाता था. Bazel 8 (2024 में रिलीज़ किया गया) ने इन नियमों के लिए सहायता बंद कर दी है, क्योंकि इनमें से कई नियमों को Starlark भाषा में माइग्रेट कर दिया गया था. ज़्यादा जानकारी के लिए, "Bazel 8.0 LTS के बारे में ब्लॉग पोस्ट" पढ़ें.
लेगसी नेटिव Android नियमों में, मोबाइल ऐप्लिकेशन इंस्टॉल करने से जुड़ी सुविधा के लेगसी नेटिव वर्शन का भी इस्तेमाल किया जा सकता था. इसे अब "मोबाइल-इंस्टॉल v1" या "नेटिव मोबाइल-इंस्टॉल" कहा जाता है. इस सुविधा को Bazel 8 में हटा दिया गया था. साथ ही, Android के बिल्ट-इन नियमों को भी हटा दिया गया था.
अब मोबाइल पर ऐप्लिकेशन इंस्टॉल करने से जुड़ी सभी सुविधाएं, साथ ही Android के सभी बिल्ड और टेस्ट के नियम, Starlark में लागू किए गए हैं. ये rules_android
GitHub रिपॉज़िटरी में मौजूद हैं. नए वर्शन को "मोबाइल-इंस्टॉल v3" या "MIv3" कहा जाता है.
नाम से जुड़ी जानकारी: Google में एक समय "mobile-install v2" उपलब्ध था. हालांकि, इसे कभी भी बाहरी तौर पर पब्लिश नहीं किया गया था. साथ ही, Google के अंदरूनी और OSS rules_android डिप्लॉयमेंट, दोनों के लिए सिर्फ़ v3 का इस्तेमाल किया जाता है.