bazel मोबाइल-इंस्टॉल

Android के लिए, तेज़ी से इटरेटिव डेवलपमेंट

इस पेज पर बताया गया है कि bazel mobile-install, Android के लिए बार-बार डेवलपमेंट करने की प्रोसेस को कैसे ज़्यादा तेज़ बनाता है. इसमें, अलग-अलग बिल्ड और इंस्टॉल करने के चरणों की कमियों के मुकाबले, इस तरीके के फ़ायदों के बारे में बताया गया है.

खास जानकारी

Android ऐप्लिकेशन में छोटे-मोटे बदलावों को तुरंत इंस्टॉल करने के लिए, यह तरीका अपनाएं:

  1. उस ऐप्लिकेशन का android_binary नियम ढूंढें जिसे आपको इंस्टॉल करना है.
  2. अपने डिवाइस को adb से कनेक्ट करें.
  3. bazel mobile-install :your_target शुरू करें. ऐप्लिकेशन को चालू होने में सामान्य से थोड़ा ज़्यादा समय लगेगा.
  4. कोड या Android संसाधनों में बदलाव करें.
  5. bazel mobile-install :your_target शुरू करें.
  6. तेज़ी से और कम समय में इंक्रीमेंटल इंस्टॉलेशन का आनंद लें!

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 फ़ाइलों को फिर से कंपाइल किया जाता है जिनमें बदलाव किया गया है.

  • शार्ड किया गया इंस्टॉलेशन. मोबाइल-इंस्टॉल, Android Studio के apkdeployer टूल का इस्तेमाल करता है. इससे कनेक्ट किए गए डिवाइस पर, शेयर किए गए APK को एक साथ जोड़ा जा सकता है और एक बेहतर अनुभव दिया जा सकता है.

शार्ड की गई डेक्सिंग

शार्ड की गई डेक्सिंग का तरीका काफ़ी आसान है: .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 से पहले के वर्शन में, mobile-install के लिए कुछ अतिरिक्त फ़्लैग तय करने होंगे. 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 के इंटरनल और ओएसएस rules_android डिप्लॉयमेंट, दोनों के लिए सिर्फ़ v3 का इस्तेमाल किया जाता है.