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