Computer >> कंप्यूटर ट्यूटोरियल >  >> प्रणाली >> Android

ऐप आर्किटेक्चर में मास्टरी: विश्वसनीय, स्केलेबल डेवलपमेंट के लिए पैटर्न्स चुनना

Kriptofolio ऐप सीरीज़ - भाग 3

एक नया ऐप बनाना शुरू करते समय सबसे महत्वपूर्ण चीज जिस पर ध्यान केंद्रित करना चाहिए वह है आर्किटेक्चर। सबसे बड़ी गलती जो आप कर सकते हैं वह है बिना किसी आर्किटेक्चर स्टाइल के आगे बढ़ना।

आर्किटेक्चर चॉइस का विषय हाल के वर्षों में Android कम्युनिटी के लिए काफी विवादास्पद रहा है। यहां तक कि Google ने भी इसमें शामिल होने का फैसला किया। 2017 में उन्होंने Android Architecture Components जारी करके स्टैंडर्डाइज़्ड आर्किटेक्चर का अपना दृष्टिकोण प्रस्तावित किया। इसका उद्देश्य डेवलपर्स के जीवन को आसान बनाना था।

इस पोस्ट में, मैं पहले चर्चा करूंगा कि हमें अपने ऐप्स को आर्किटेक्ट करने की आवश्यकता क्यों है। हम देखेंगे कि हमारे पास क्या विकल्प हैं। फिर हम सीखेंगे कि यह कैसे करना है। पहिया को फिर से आविष्कार करने के बजाय, हम Android टीम द्वारा प्रदान किए गए दिशानिर्देशों का उपयोग करेंगे।

यह पोस्ट मेरे लिए लिखने में सबसे कठिन थी क्योंकि इस विषय पर मेरा अपना ज्ञान कम था। पहले मुझे आर्किटेक्चर के विषय का वास्तव में अच्छी तरह से अध्ययन करना पड़ा ताकि मैं बड़ी तस्वीर देख सकूं। अब मैं अपने निष्कर्ष आपके साथ साझा करने के लिए तैयार हूँ।

सीरीज़ कंटेंट

  • परिचय: 2018-2019 में एक आधुनिक Android ऐप बनाने का रोडमैप
  • भाग 1: SOLID सिद्धांतों का परिचय
  • भाग 2: अपना Android ऐप बनाना शुरू कैसे करें: मॉकअप्स, UI, और XML लेआउट्स बनाना
  • भाग 3: आर्किटेक्चर के बारे में सब कुछ: विभिन्न आर्किटेक्चर पैटर्न्स की खोज और उन्हें अपने ऐप में कैसे उपयोग करें (आप यहाँ हैं)
  • भाग 4: Dagger 2 के साथ अपने ऐप में डिपेंडेंसी इंजेक्शन कैसे इम्प्लीमेंट करें
  • भाग 5: Retrofit, OkHttp, Gson, Glide और Coroutines का उपयोग करके RESTful वेब सर्विसेज को हैंडल करना

ऐप आर्किटेक्चर की परवाह क्यों करनी चाहिए?

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

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

मूल रूप से आपका सारा कोड स्पेगेटी की तरह दिखने लगता है जहां सब कुछ मिक्स हो जाता है। सभी पार्ट्स एक-दूसरे पर निर्भर करते हैं। फिर जब बिजनेस द्वारा नए परिवर्तनों की आवश्यकता होती है, तो आपके पास पूरे प्रोजेक्ट को रीबिल्ड करने के अलावा कोई विकल्प नहीं बचता। यहीं वह बिंदु है जहां आर्किटेक्चर के सवाल उठने लगते हैं।

क्या आपके कोड को स्ट्रक्चर करने का कोई बेहतर तरीका है?

बेशक है! उच्च गुणवत्ता वाले कोड की कुंजी SOLID सिद्धांतों का पालन करना है। मैंने इसके बारे में अपनी पिछली पोस्ट में बात की थी (बिना किसी कारण के नहीं)। आपको सेपरेशन ऑफ कंसर्न्स के लिए कुछ आर्किटेक्चर पैटर्न भी लागू करना चाहिए। वास्तव में, सेपरेशन ऑफ कंसर्न्स आपका अंतिम लक्ष्य होना चाहिए। यह सबसे महत्वपूर्ण बिंदु है जो कोड गुणवत्ता को दर्शाता है। ऐप आर्किटेक्चर के लिए काफी कुछ पैटर्न्स मौजूद हैं। सबसे प्रसिद्ध क्लासिक थ्री-टियर आर्किटेक्चर हैं जैसे:

  • MVC: Model-View-Controller
  • MVP: Model-View-Presenter
  • MVVM: Model-View-ViewModel

ये सभी पैटर्न मुख्य समान विचार को दर्शाते हैं - अपने प्रोजेक्ट के कोड को इस तरह से स्ट्रक्चर करना कि यह अलग-अलग जेनेरिक लेयर्स द्वारा अलग हो जाए। प्रत्येक लेयर की अपनी जिम्मेदारी होती है। इसीलिए आपका प्रोजेक्ट मॉड्यूलर बन जाता है: अलग किए गए कोड पार्ट्स अधिक टेस्टेबल होते हैं, और आपका ऐप निरंतर परिवर्तनों के लिए पर्याप्त फ्लेक्सिबल होता है।

यदि हम प्रत्येक पैटर्न के बारे में व्यक्तिगत रूप से बात करते हैं, तो विषय बहुत व्यापक हो जाता है। मैं आपको केवल प्रत्येक से परिचित कराने जा रहा हूँ ताकि आप मुख्य अंतर समझ सकें।

Model-View-Controller (MVC) पैटर्न

यह पैटर्न पुराने समय में Android ऐप आर्किटेक्चर की पहली पुनरावृत्ति थी। यह सुझाव देता है कि आप अपने कोड को 3 अलग-अलग लेयर्स में अलग करें:

Model - डेटा लेयर। बिजनेस लॉजिक को संभालने और नेटवर्क और डेटाबेस लेयर्स के साथ कम्युनिकेशन के लिए जिम्मेदार।

View - यूज़र इंटरफेस (UI) लेयर। यह Model से डेटा का एक सिंपल विज़ुअलाइज़ेशन है।

Controller - लॉजिक लेयर, यूज़र बिहेवियर की सूचना प्राप्त करता है और आवश्यकतानुसार Model को अपडेट करता है।

ऐप आर्किटेक्चर में मास्टरी: विश्वसनीय, स्केलेबल डेवलपमेंट के लिए पैटर्न्स चुनना

यह MVC स्कीमा है। इसमें हम देख सकते हैं कि Controller और View दोनों Model पर निर्भर करते हैं। Controller डेटा को अपडेट करता है। View डेटा प्राप्त करता है। हालांकि, Model अलग है और UI से स्वतंत्र रूप से टेस्ट किया जा सकता है।

MVC पैटर्न लागू करने के कुछ दृष्टिकोण हैं। यह काफी भ्रमित करने वाला है।

एक वह है जब एक्टिविटीज़ और फ्रैगमेंट्स Controller की तरह काम करते हैं। वे डेटा प्रोसेस करने और व्यूज़ अपडेट करने के प्रभारी होते हैं। इस आर्किटेक्चर दृष्टिकोण की समस्या यह है कि एक्टिविटीज़ और फ्रैगमेंट्स काफी बड़े और टेस्ट करने में बहुत कठिन हो सकते हैं।

एक अन्य दृष्टिकोण जो अधिक तार्किक (और सही) लगता है वह है जहां एक्टिविटीज़ और फ्रैगमेंट्स MVC दुनिया में Views होने चाहिए। Controllers को अलग क्लासेज होना चाहिए जो किसी Android क्लास को एक्सटेंड या उपयोग न करें। Models के लिए भी यही बात लागू होती है।

वैसे भी यदि आप MVC के बारे में अधिक जांच करते हैं, तो आप पाएंगे कि Android प्रोजेक्ट पर लागू होने पर, सही तरीके से भी कोड लेयर्स एक-दूसरे पर निर्भर करती हैं। इसलिए मैं आपके अगले Android ऐप के लिए इसका उपयोग करने की अनुशंसा नहीं करूंगा।

Model-View-Presenter (MVP) पैटर्न

पहले दृष्टिकोण के काम न करने के बाद, Android डेवलपर्स आगे बढ़े और सबसे लोकप्रिय आर्किटेक्चरल पैटर्न्स में से एक - MVP का उपयोग करने की कोशिश की। यह पैटर्न आर्किटेक्चर चॉइस की दूसरी पुनरावृत्ति को दर्शाता है। यह पैटर्न व्यापक रूप से उपयोग किया गया और अभी भी एक अनुशंसित है। जो कोई भी Android डेवलपमेंट शुरू करता है, उसके लिए यह सीखना आसान है। आइए इसके 3 अलग-अलग लेयर्स की भूमिकाओं पर एक नज़र डालें:

Model - डेटा लेयर, जो MVC पैटर्न के समान है। बिजनेस लॉजिक को संभालने और नेटवर्क और डेटाबेस लेयर्स के साथ कम्युनिकेशन के लिए जिम्मेदार।

View - यूज़र इंटरफेस (UI) लेयर। डेटा प्रदर्शित करता है और यूज़र एक्शन्स के बारे में Presenter को सूचित करता है।

Presenter - Model से डेटा प्राप्त करता है, UI लॉजिक लागू करता है और View की स्थिति को मैनेज करता है, तय करता है कि क्या प्रदर्शित करना है, और View से यूज़र इनपुट नोटिफिकेशन्स पर प्रतिक्रिया करता है। यह अनिवार्य रूप से MVC से Controller है सिवाय इसके कि यह View से बिल्कुल भी जुड़ा नहीं है, सिर्फ एक इंटरफेस है।

ऐप आर्किटेक्चर में मास्टरी: विश्वसनीय, स्केलेबल डेवलपमेंट के लिए पैटर्न्स चुनना

MVP स्कीमा दर्शाता है कि View और Presenter निकटता से संबंधित हैं। उन्हें एक-दूसरे का रेफरेंस रखने की आवश्यकता है। उनका रिलेशनशिप एक Contract इंटरफेस क्लास में परिभाषित है।

इस पैटर्न का एक महत्वपूर्ण लेकिन नियंत्रणीय नुकसान है। यदि आप पर्याप्त सावधान नहीं हैं और अपने कोड को सिंगल रिस्पॉन्सिबिलिटी सिद्धांत के अनुसार नहीं तोड़ते हैं तो Presenter एक विशाल सर्वज्ञानी क्लास में विस्तारित हो जाता है। हालांकि, आम तौर पर बोलते हुए, MVP पैटर्न चिंताओं का एक बहुत अच्छा विभाजन प्रदान करता है। यह आपके प्रोजेक्ट के लिए आपकी मुख्य पसंद हो सकती है।

Model-View-ViewModel (MVVM) पैटर्न

MVVM पैटर्न दृष्टिकोण की तीसरी पुनरावृत्ति है। Android Architecture Components के रिलीज़ के साथ यह Android टीम द्वारा अनुशंसित आर्किटेक्चर पैटर्न बन गया। इसलिए हम इस पैटर्न को सीखने पर सबसे अधिक ध्यान केंद्रित करेंगे। साथ ही मैं इसे "My Crypto Coins" ऐप के लिए उपयोग करूंगा। पहले की तरह, आइए इसके अलग-अलग कोड लेयर्स पर एक नज़र डालें:

Model - डेटा स्रोत को एब्सट्रैक्ट करता है। ViewModel डेटा प्राप्त करने और सेव करने के लिए Model के साथ काम करता है।

View - जो यूज़र्स के एक्शन्स के बारे में ViewModel को सूचित करता है।

ViewModel - View के लिए प्रासंगिक डेटा की स्ट्रीम्स को एक्सपोज़ करता है।

MVP पैटर्न की तुलना में अंतर यह है कि, MVVM में, ViewModel, Presenter के साथ जैसा होता है, View का रेफरेंस नहीं रखता। MVVM में, ViewModel इवेंट्स की एक स्ट्रीम एक्सपोज़ करता है जिससे विभिन्न Views बाइंड कर सकते हैं। दूसरी ओर, MVP केस में, Presenter सीधे View को बताता है कि क्या प्रदर्शित करना है। आइए MVVM स्कीमा पर एक नज़र डालें:

ऐप आर्किटेक्चर में मास्टरी: विश्वसनीय, स्केलेबल डेवलपमेंट के लिए पैटर्न्स चुनना

MVVM में View का ViewModel का रेफरेंस होता है। ViewModel को View के बारे में कोई जानकारी नहीं होती। View और ViewModel के बीच कई-से-एक रिलेशनशिप होता है।

MVC vs MVP vs MVVM की तुलना

यहां एक टेबल है जो उन सभी पैटर्न्स को सारांशित करती है जिनके बारे में मैंने बात की:

ऐप आर्किटेक्चर में मास्टरी: विश्वसनीय, स्केलेबल डेवलपमेंट के लिए पैटर्न्स चुनना

जैसा कि आपने देखा होगा, एक मॉड्यूलर और टेस्टेबल आधुनिक ऐप बनाते समय MVC, MVP और MVVM की तुलना में इतना अच्छा नहीं है। लेकिन प्रत्येक पैटर्न के अपने फायदे और नुकसान हैं। यह एक अच्छा विकल्प है यदि यह आपकी आवश्यकताओं को बिल्कुल फिट करता है। मेरा सुझाव है कि आप इन सभी पैटर्न्स के बारे में अधिक जांच करें और सीखें क्योंकि यह इसके लायक है।

इस बीच, मैं 2018 में ट्रेंडिंग पैटर्न के साथ अपना प्रोजेक्ट जारी रखूंगा, जिसे Google द्वारा भी आगे बढ़ाया जा रहा है - MVVM।

Android Architecture Components

यदि आप Android ऐप्लिकेशन लाइफसाइकिल से परिचित हैं, तो आप जानते हैं कि एक ऐसा ऐप बनाना जो सभी डेटा फ्लो समस्याओं और पर्सिस्टेंस और स्टेबिलिटी मुद्दों से बचता है जो आमतौर पर कॉन्फ़िगरेशन चेंज के दौरान दिखाई देते हैं, कितना बड़ा सिरदर्द हो सकता है।

2017 में, Android टीम ने फैसला किया कि हमने काफी संघर्ष किया है। उन्होंने जिम्मेदारी ली और Android Architecture Components फ्रेमवर्क पेश किया। यह अंततः आपको इन सभी मुद्दों को अपने कोड को जटिल बनाए बिना या यहां तक कि हैक्स लागू किए बिना हल करने देता है।

Android Architecture Components लाइब्रेरीज़ का एक संग्रह है जो आपको मजबूत, टेस्टेबल और मेंटेनेबल ऐप्स डिज़ाइन करने में मदद करता है। इस ब्लॉग पोस्ट को लिखते समय वर्तमान क्षण में, इसमें ये कंपोनेंट्स शामिल हैं:

  • Data Binding - UI एलिमेंट्स को ऑब्जर्वेबल डेटा से डिक्लेरेटिवली बाइंड करें
  • Lifecycles - अपनी एक्टिविटी और फ्रैगमेंट लाइफसाइकिल्स को मैनेज करें
  • LiveData - जब अंडरलाइंग डेटाबेस बदलता है तो व्यूज़ को सूचित करें
  • Navigation - इन-ऐप नेविगेशन के लिए आवश्यक सब कुछ हैंडल करें
  • Paging - अपने डेटा स्रोत से ऑन-डिमांड जानकारी धीरे-धीरे लोड करें
  • Room - फ्लुएंट SQLite डेटाबेस एक्सेस
  • ViewModel - जीवनचक्र-जागरूक तरीके से UI-संबंधित डेटा मैनेज करें
  • WorkManager - अपने Android बैकग्राउंड जॉब्स मैनेज करें

Android Architecture Components की मदद से हम इस डायग्राम का पालन करते हुए My Crypto Coins ऐप में MVVM आर्किटेक्चर पैटर्न इम्प्लीमेंट करने जा रहे हैं:

ऐप आर्किटेक्चर में मास्टरी: विश्वसनीय, स्केलेबल डेवलपमेंट के लिए पैटर्न्स चुनना

यह Google द्वारा अनुशंसित आर्किटेक्चर है। यह दर्शाता है कि सभी मॉड्यूल्स को एक-दूसरे के साथ कैसे इंटरैक्ट करना चाहिए। अगला हम केवल उन विशिष्ट Android Architecture Components को कवर करेंगे जिनका उपयोग हम अपने प्रोजेक्ट में करेंगे।

अपनी सोर्स फाइल्स को व्यवस्थित करना

विकास शुरू करने से पहले हमें इस बात पर विचार करना चाहिए कि हमें अपने प्रोजेक्ट की सोर्स फाइल्स को कैसे व्यवस्थित करना चाहिए। हम इस सवाल को अनुत्तरित नहीं छोड़ सकते, क्योंकि बाद में हमारे पास एक गन्दी संरचना होगी जिसे समझना और संशोधित करना कठिन होगा।

इसे करने के कई तरीके हैं। एक है कंपोनेंट कैटेगरी द्वारा व्यवस्थित करना। उदाहरण के लिए, सभी एक्टिविटीज़ अपने स्वयं के फोल्डर में जाती हैं, सभी एडाप्टर्स अपने फोल्डर में जाते हैं और इसी तरह।

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

ऐप आर्किटेक्चर में मास्टरी: विश्वसनीय, स्केलेबल डेवलपमेंट के लिए पैटर्न्स चुनना
My Crypto Coins ऐप फोल्डर संरचना

प्रोजेक्ट की फोल्डर संरचना के अलावा, आपको प्रोजेक्ट फाइलों के नामकरण के लिए कुछ नियम लागू करने पर विचार करना चाहिए। उदाहरण के लिए, Android क्लासेज का नामकरण करते समय आपको क्लास के उद्देश्य को नाम में स्पष्ट रूप से परिभाषित करना चाहिए।

ViewModel

हमारे ऐप आर्किटेक्चर डेवलपमेंट की शुरुआत के लिए, पहले हम ViewModel बनाने जा रहे हैं। View models ऑब्जेक्ट्स हैं जो UI कंपोनेंट्स के लिए डेटा प्रदान करते हैं और कॉन्फ़िगरेशन चेंजेज से बचे रहते हैं।

आप एक्टिविटी या फ्रैगमेंट के पूरे लाइफसाइकिल में डेटा को बनाए रखने के लिए ViewModel का उपयोग कर सकते हैं। एक्टिविटीज़ और फ्रैगमेंट्स शॉर्ट-लिव्ड ऑब्जेक्ट्स हैं। यूज़र ऐप के साथ इंटरैक्ट करते ही वे बार-बार बनाए और नष्ट किए जाते हैं। ViewModel नेटवर्क कम्युनिकेशन से संबंधित कार्यों को मैनेज करने के साथ-साथ डेटा मैनिपुलेशन और पर्सिस्टेंस के लिए भी बेहतर अनुकूल है।

उदाहरण के तौर पर अब MainListFragment के लिए एक ViewModel बनाते हैं ताकि UI डेटा को इससे अलग किया जा सके।

class MainViewModel : ViewModel() { ... }

फिर एक लाइन कोड के साथ ViewModel प्राप्त करें।

class MainListFragment : Fragment() { ... private lateinit var viewModel: MainViewModel ... override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) setupList() // इस फ्रैगमेंट को LifecycleOwner के रूप में उपयोग करके ViewModelProviders से ViewModel प्राप्त करें। viewModel = ViewModelProviders.of(this).get(MainViewModel::class.java) ... } ... }

मूल रूप से बस इतना ही, बधाई हो! आइए आगे बढ़ते हैं।

LiveData

LiveData एक ऑब्जर्वेबल डेटा होल्डर क्लास है। यह ऑब्जर्वर पैटर्न का पालन करता है। LiveData लाइफसाइकिल-अवेयर है। इसका मतलब है कि यह केवल उन ऐप कंपोनेंट (एक्टिविटी, फ्रैगमेंट, आदि) ऑब्जर्वर्स को अपडेट करता है जो एक्टिव लाइफसाइकिल स्टेट में हैं।

LiveData क्लास डेटा का नवीनतम मान लौटाती है। जब डेटा बदलता है तो यह अपडेटेड मान लौटाती है। LiveData ViewModel के साथ सबसे उपयुक्त है।

हम ViewModel के साथ LiveData का उपयोग इस तरह करेंगे:

... class MainViewModel : ViewModel() { private val liveData = MutableLiveData<ArrayList<Cryptocurrency>>() val data: LiveData<ArrayList<Cryptocurrency>> get() = liveData init { val tempData = ArrayList<Cryptocurrency>() val btc:Cryptocurrency = Cryptocurrency("Bitcoin", 1, 0.56822348, "BTC", 8328.77, 4732.60, 0.19, -10.60, 0.44, 20.82) val eth:Cryptocurrency = Cryptocurrency("Etherium", 2, 6.0, "ETH", 702.99, 4217.94, 0.13, -7.38, 0.79, 33.32) tempData.add(btc) tempData.add(eth) liveData.value = tempData } }

ViewModel पर एक्सपोज़्ड LiveData के रूप में डेटा ऑब्जर्व करें:

... class MainListFragment : Fragment() { private lateinit var recyclerView: RecyclerView private lateinit var recyclerAdapter: MainRecyclerViewAdapter private lateinit var viewModel: MainViewModel ... override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) setupList() // इस फ्रैगमेंट को LifecycleOwner के रूप में उपयोग करके ViewModelProviders से ViewModel प्राप्त करें। viewModel = ViewModelProviders.of(this).get(MainViewModel::class.java) // ViewModel पर एक्सपोज़्ड LiveData के रूप में डेटा ऑब्जर्व करें viewModel.data.observe(this, Observer { data -> // LiveData द्वारा एक्सपोज़्ड डेटा सेट करें if (data != null) { recyclerAdapter.setData(data) } }) } ... }

इस बिंदु पर इतिहास में रिपॉजिटरी ब्राउज़ करें।

Data Binding

Data Binding Library को XML लेआउट्स से कनेक्ट करने के लिए आवश्यक बॉयलरप्लेट कोड को हटाने के लिए बनाया गया था।

अपने Kotlin प्रोजेक्ट्स में Data Binding का उपयोग करने के लिए, आपको kapt कंपाइलर प्लगइन के साथ एनोटेशन प्रोसेसर्स के लिए सपोर्ट ऑन करना होगा। साथ ही Android कॉन्फ़िगरेशन gradle फ़ाइल में data binding ब्लॉक जोड़ें:

... apply plugin: 'kotlin-kapt' android { ... dataBinding { enabled = true } } ...

Data Binding जनरेटेड क्लासेज का उपयोग करने के लिए, हमें सभी व्यू कोड को <layout> टैग्स में रखना होगा। Data Binding की सबसे शक्तिशाली अवधारणा यह है कि हम किसी डेटा क्लास को XML लेआउट से बाइंड कर सकते हैं और आइटम प्रॉपर्टीज़ को सीधे फील्ड्स से बाइंड कर सकते हैं।

<layout xmlns:app="https://schemas.android.com/apk/res-auto" xmlns:tools="https://schemas.android.com/tools"> <data> <variable name="cryptocurrency" type="com.baruckis.mycryptocoins.data.Cryptocurrency" /> </data> ... <android.support.v7.widget.AppCompatTextView android:id="@+id/item_name" style="@style/MainListItemPrimeText" android:layout_marginEnd="@dimen/main_cardview_list_item_text_between_margin" android:layout_marginStart="@dimen/main_cardview_list_item_inner_margin" android:text="@{cryptocurrency.name}" android:textAlignment="viewStart" app:layout_constraintBottom_toTopOf="@+id/item_amount_symbol" app:layout_constraintEnd_toStartOf="@+id/guideline1_percent" app:layout_constraintStart_toEndOf="@+id/item_image_icon" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_chainStyle="spread" tools:text="@string/sample_text_item_name" /> ... </layout>

Data Binding के साथ RecyclerView एडाप्टर इस तरह दिखेगा:

class MainRecyclerViewAdapter() : RecyclerView.Adapter<MainRecyclerViewAdapter.BindingViewHolder>() { private lateinit var dataList: ArrayList<Cryptocurrency> fun setData(newDataList: ArrayList<Cryptocurrency>) { dataList = newDataList } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BindingViewHolder { val inflater = LayoutInflater.from(parent.context) val binding = FragmentMainListItemBinding.inflate(inflater, parent, false) return BindingViewHolder(binding) } override fun onBindViewHolder(holder: BindingViewHolder, position: Int) = holder.bind(dataList[position]) override fun getItemCount(): Int = dataList.size ... inner class BindingViewHolder(var binding: FragmentMainListItemBinding) : RecyclerView.ViewHolder(binding.root) { fun bind(cryptocurrency: Cryptocurrency) { binding.cryptocurrency = cryptocurrency binding.itemRanking.text = String.format("${cryptocurrency.rank}") ... binding.executePendingBindings() } } }

अंत में अब findViewById लिखने की आवश्यकता नहीं! इस बिंदु पर इतिहास में रिपॉजिटरी ब्राउज़ करें।

Room

हमारे ऐप को विभिन्न क्रिप्टोकरेंसीज़ का पर्सिस्टेंट डेटा स्टोर करने की आवश्यकता है जो यूज़र के पास हैं। इसे Android डिवाइस के अंदर प्राइवेट रखे जाने वाले लोकल डेटाबेस में स्टोर किया जाना चाहिए।

प्राइवेट डेटाबेस में स्ट्रक्चर्ड डेटा स्टोर करने के लिए हम SQLite डेटाबेस का उपयोग करेंगे। यह अक्सर सबसे अच्छा विकल्प होता है।

हमारे ऐप के लिए SQLite डेटाबेस बनाने के लिए हम Room का उपयोग करेंगे। Room Android टीम द्वारा बनाया गया एक पर्सिस्टेंस लाइब्रेरी है जो SQLite के ऊपर एक रैपर है। यह एक एब्सट्रैक्शन लेयर है जो SQLite के साथ इंटरैक्ट करने के लिए आवश्यक अधिकांश बॉयलरप्लेट कोड को हटा देता है। यह आपके SQL क्वेरीज़ की कंपाइल-टाइम चेकिंग भी जोड़ता है।

इसे सोचने का सबसे अच्छा तरीका यह है कि यह एक ORM (ऑब्जेक्ट रिलेशनल मैपर) टूल है जिसे आपके ऑब्जेक्ट इंस्टेंसेस और आपके डेटाबेस में पंक्तियों के बीच मैप करने के लिए ग्लू कोड को ऑटोमेटिकली जनरेट करने के लिए डिज़ाइन किया गया है।

Room में मूल रूप से 3 प्रमुख कंपोनेंट्स हैं:

  1. Entity - यह कंपोनेंट एक क्लास को दर्शाता है जो डेटाबेस पंक्ति रखता है। प्रत्येक एंटिटी के लिए, आइटम्स को रखने के लिए एक डेटाबेस टेबल बनाई जाती है।
  2. DAO (Data Access Object) - मुख्य कंपोनेंट जो डेटाबेस को एक्सेस करने वाले मेथड्स को परिभाषित करने के लिए जिम्मेदार है।
  3. Database - एक कंपोनेंट जो एक होल्डर क्लास है जो एनोटेशन का उपयोग करके एंटिटीज़ की सूची, DAOs की सूची, और डेटाबेस संस्करण को परिभाषित करता है और अंडरलाइंग कनेक्शन के लिए मुख्य एक्सेस पॉइंट के रूप में कार्य करता है।
ऐप आर्किटेक्चर में मास्टरी: विश्वसनीय, स्केलेबल डेवलपमेंट के लिए पैटर्न्स चुनना

आइए My Crypto Coins ऐप में Room सेटअप करने के लिए इन सरल चरणों का पालन करें:

  1. एक Entity बनाएं।
@Entity data class Cryptocurrency(val name: String, val rank: Short, val amount: Double, @PrimaryKey val symbol: String, val price: Double, val amountFiat: Double, val pricePercentChange1h: Double, val pricePercentChange7d: Double, val pricePercentChange24h: Double, val amountFiatChange24h: Double)

डेटाबेस में इसकी संरचना के बारे में Room को बताने के लिए कुछ अतिरिक्त जानकारी जोड़ें।

2. DAO बनाएं।

@Dao interface MyCryptocurrencyDao { @Query("SELECT * FROM Cryptocurrency") fun getMyCryptocurrencyLiveDataList(): LiveData<List<Cryptocurrency>> @Insert fun insertDataToMyCryptocurrencyList(data: List<Cryptocurrency>) }

शुरुआत के लिए, हम एक DAO बनाने जा रहे हैं जो केवल हमें Entity के साथ बनाई गई टेबल से रिकॉर्ड्स प्राप्त करने और कुछ सैंपल डेटा इन्सर्ट करने की अनुमति देता है।

3. Database बनाएं और सेटअप करें।

यह कहना महत्वपूर्ण है कि Database इंस्टेंस को आदर्श रूप से प्रति सत्र केवल एक बार बनाया जाना चाहिए। इसे प्राप्त करने का एक तरीका सिंगलटन पैटर्न का उपयोग करना होगा।

@Database(entities = [Cryptocurrency::class], version = 1, exportSchema = false) abstract class AppDatabase : RoomDatabase() { abstract fun myCryptocurrencyDao(): MyCryptocurrencyDao // AppDatabase एक सिंगलटन ताकि एक ही समय में डेटाबेस के कई इंस्टेंसेस खुले न हों। companion object { // एनोटेटेड प्रॉपर्टी के JVM बैकिंग फील्ड को वोलेटाइल के रूप में मार्क करता है, जिसका अर्थ है कि इस फील्ड में लिखे गए मान अन्य थ्रेड्स को तुरंत दिखाई देते हैं। @Volatile private var instance: AppDatabase? = null // सिंगलटन इंस्टेंटिएशन के लिए। fun getInstance(context: Context): AppDatabase { return instance ?: synchronized(this) { instance ?: buildDatabase(context).also { instance = it } } } // डेटाबेस बनाता है और प्री-पॉप्युलेट करता है। private fun buildDatabase(context: Context): AppDatabase { return Room.databaseBuilder(context, AppDatabase::class.java, DATABASE_NAME) // onCreate कॉल होने के बाद डेटाबेस को प्रीपॉप्युलेट करें। .addCallback(object : Callback() { override fun onCreate(db: SupportSQLiteDatabase) { super.onCreate(db) // IO थ्रेड पर डेटा इन्सर्ट करें। ioThread { getInstance(context).myCryptocurrencyDao().insertDataToMyCryptocurrencyList(PREPOPULATE_DATA) } } }) .build() } // सैंपल डेटा। val btc: Cryptocurrency = Cryptocurrency("Bitcoin", 1, 0.56822348, "BTC", 8328.77, 4732.60, 0.19, -10.60, 0.44, 20.82) val eth: Cryptocurrency = Cryptocurrency("Etherium", 2, 6.0, "ETH", 702.99, 4217.94, 0.13, -7.38, 0.79, 33.32) val PREPOPULATE_DATA = listOf(btc, eth) } }
private val IO_EXECUTOR = Executors.newSingleThreadExecutor() // समर्पित बैकग्राउंड थ्रेड पर ब्लॉक्स चलाने के लिए यूटिलिटी मेथड, IO/डेटाबेस कार्य के लिए उपयोग किया जाता है। fun ioThread(f : () -> Unit) { IO_EXECUTOR.execute(f) }

जैसा कि आप देख सकते हैं प्रारंभिक रन पर, डेटाबेस केवल टेस्टिंग उद्देश्यों के लिए कुछ सैंपल डेटा के साथ प्रीपॉप्युलेटेड होगा।

4. अतिरिक्त चरण। Repository बनाएं।

Repository Architecture Components लाइब्रेरीज़ का हिस्सा नहीं है। यह कोड सेपरेशन और आर्किटेक्चर के लिए एक सुझाई गई बेस्ट प्रैक्टिस है।

ऐप आर्किटेक्चर में मास्टरी: विश्वसनीय, स्केलेबल डेवलपमेंट के लिए पैटर्न्स चुनना

यह ऐप के सभी डेटा के लिए सिंगल सोर्स ऑफ ट्रुथ के रूप में खड़ा होता है यदि आपको कई डेटा स्रोतों को मैनेज करना है।

class MyCryptocurrencyRepository private constructor( private val myCryptocurrencyDao: MyCryptocurrencyDao ) { fun getMyCryptocurrencyLiveDataList(): LiveData<List<Cryptocurrency>> { return myCryptocurrencyDao.getMyCryptocurrencyLiveDataList() } companion object { // एनोटेटेड प्रॉपर्टी के JVM बैकिंग फील्ड को वोलेटाइल के रूप में मार्क करता है, जिसका अर्थ है कि इस फील्ड में लिखे गए मान अन्य थ्रेड्स को तुरंत दिखाई देते हैं। @Volatile private var instance: MyCryptocurrencyRepository? = null // सिंगलटन इंस्टेंटिएशन के लिए। fun getInstance(myCryptocurrencyDao: MyCryptocurrencyDao) = instance ?: synchronized(this) { instance ?: MyCryptocurrencyRepository(myCryptocurrencyDao).also { instance = it } } } }

हम इस रिपॉजिटरी का उपयोग अपने ViewModel में करेंगे।

class MainViewModel(myCryptocurrencyRepository: MyCryptocurrencyRepository) : ViewModel() { val liveData = myCryptocurrencyRepository.getMyCryptocurrencyLiveDataList() }

हमारा फ्रैगमेंट कोड भी विकसित होता है।

class MainListFragment : Fragment() { ... private lateinit var viewModel: MainViewModel ... override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) setupList() subscribeUi() } ... private fun subscribeUi() { val factory = InjectorUtils.provideMainViewModelFactory(requireContext()) // इस फ्रैगमेंट को LifecycleOwner के रूप में उपयोग करके ViewModelProviders से ViewModel प्राप्त करें। viewModel = ViewModelProviders.of(this, factory).get(MainViewModel::class.java) // ViewModel पर एक्सपोज़्ड LiveData के रूप में डेटा ऑब्जर्व करके जब डेटा बैकएंड में बदलता है तो लिस्ट अपडेट करें। viewModel.liveData.observe(this, Observer<List<Cryptocurrency>> { data -> if (data != null && data.isNotEmpty()) { emptyListView.visibility = View.GONE recyclerView.visibility = View.VISIBLE recyclerAdapter.setData(data) } else { recyclerView.visibility = View.GONE emptyListView.visibility = View.VISIBLE } }) } }

क्योंकि हमारा ViewModel क्लास अब एक कंस्ट्रक्टर है जो अब खाली नहीं है, हमें प्रोवाइडर फैक्ट्री पैटर्न इम्प्लीमेंट करने की आवश्यकता है। इसे ViewModelProviders.of() मेथड में दूसरे पैरामीटर के रूप में पास किया जाएगा।

object InjectorUtils { fun provideMainViewModelFactory( context: Context ): MainViewModelFactory { val repository = getMyCryptocurrencyRepository(context) return MainViewModelFactory(repository) } private fun getMyCryptocurrencyRepository(context: Context): MyCryptocurrencyRepository { return MyCryptocurrencyRepository.getInstance( AppDatabase.getInstance(context).myCryptocurrencyDao()) } }
class MainViewModelFactory(private val repository: MyCryptocurrencyRepository) : ViewModelProvider.NewInstanceFactory() { override fun <T : ViewModel?> create(modelClass: Class<T>): T { return MainViewModel(repository) as T } }

इस बिंदु पर इतिहास में रिपॉजिटरी ब्राउज़ करें।

अंतिम विचार

डिज़ाइन आर्किटेक्चर, जिन पर हमने इस भाग में चर्चा की, को सूचित दिशानिर्देशों के रूप में उपयोग किया जाना चाहिए न कि कठोर नियमों के रूप में। मैं प्रत्येक विषय पर बहुत अधिक विस्तार में नहीं जाना चाहता था। Android Architecture Components के साथ हमने कोडिंग प्रोसेस पर एक नज़र डाली। ध्यान रखें कि प्रत्येक कंपोनेंट पर व्यक्तिगत रूप से सीखने के लिए बहुत कुछ है और मैं आपको ऐसा करने की सलाह देता हूं।

आइए उन सभी चीज़ों को सारांशित करें जो हम अब तक बनाने में कामयाब रहे:

  • My Crypto Coins ऐप में, प्रत्येक अलग स्क्रीन का अपना ViewModel है। यह किसी भी कॉन्फ़िगरेशन चेंज से बचेगा और यूज़र को किसी भी डेटा लॉस से बचाएगा।
  • ऐप का यूज़र इंटरफेस रिएक्टिव टाइप का है। इसका मतलब है कि यह तुरंत अपडेट होगा जब बैकएंड में डेटा बदलता है। यह LiveData की मदद से किया जाता है।
  • हमारे प्रोजेक्ट में कम कोड है क्योंकि हम Data Binding का उपयोग करके अपने कोड में वेरिएबल्स को सीधे बाइंड करते हैं।
  • अंत में, हमारा ऐप यूज़र डेटा को डिवाइस के अंदर लोकली SQLite डेटाबेस के रूप में स्टोर करता है। डेटाबेस को Room कंपोनेंट के साथ सुविधाजनक रूप से बनाया गया था। ऐप का कोड फीचर्स द्वारा स्ट्रक्चर्ड है और पूरा प्रोजेक्ट आर्किटेक्चर MVVM है - Android टीम द्वारा अनुशंसित पैटर्न।

रिपॉजिटरी

अब, जैसा कि आप "Kriptofolio" (पहले "My Crypto Coins") ऐप को वास्तव में आकार लेते हुए देख रहे हैं। इस भाग 3 के लिए नवीनतम रिपॉजिटरी कमिट के साथ, आप इसे यूज़र के लिए प्रीपॉप्युलेटेड डेटाबेस डेटा को सही ढंग से कैलकुलेटेड टोटल होल्डिंग्स पोर्टफोलियो वैल्यू के साथ अच्छी तरह से दिखाते हुए पा सकते हैं।

GitHub पर सोर्स देखें

Ačiū! पढ़ने के लिए धन्यवाद! मैंने मूल रूप से यह पोस्ट अपने पर्सनल ब्लॉग www.baruckis.com पर 22 अगस्त, 2018 को प्रकाशित की थी।

  1. विंडोज़ 10 के योर फोन ऐप के साथ फोटो और फाइलों को सहजता से सिंक करें विंडोज़ 10 के योर फोन ऐप के साथ फोटो और फाइलों को सहजता से सिंक करें

    क्या आप अपने फोन से पीसी पर फोटो ट्रांसफर करते समय संघर्ष करते हैं? क्या आप खुद को ईमेल करके या अपने फोन को यूएसबी के माध्यम से जोड़कर विभिन्न उपकरणों पर फाइलों तक पहुंचते हैं? अगर हम आपको बताएं कि, आप विंडोज़ 10 की नवीनतम सुविधा का उपयोग करके इन सावधानीपूर्वक तरीकों से छुटकारा पा सकते हैं। हां, यह

  1. त्वरित गाइड: अपने विंडोज 10 पीसी पर सभी ऐप्स अपडेट करें त्वरित गाइड: अपने विंडोज 10 पीसी पर सभी ऐप्स अपडेट करें

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

  1. उत्पादकता अनलॉक करें: पर्सनल रिमाइंडर ऐप का उपयोग क्यों और कैसे करें उत्पादकता अनलॉक करें: पर्सनल रिमाइंडर ऐप का उपयोग क्यों और कैसे करें

    हे भगवान! मैं पूरी तरह भूल गया। मैं दिन में कम से कम एक-दो बार उपरोक्त कथन का उपयोग करता हूं क्योंकि मैं चीजें भूलता रहता हूं। अब मुझे पता है कि मेरे मस्तिष्क या स्वास्थ्य में कुछ भी गलत नहीं है और यह भूलने की बीमारी आज दुनिया के तेज गति से चलने के कारण है। करने के लिए बहुत कुछ है, मिलने के लिए बहुत