Jetpack Compose, Android के लिए एक मॉडर्न डिक्लेरेटिव यूज़र इंटरफ़ेस (यूआई) टूलकिट है. Compose, आपके ऐप्लिकेशन के यूज़र इंटरफ़ेस (यूआई) को लिखने और उसे मैनेज करने की प्रोसेस को आसान बनाता है. इसके लिए, यह डिक्लेरेटिव एपीआई उपलब्ध कराता है. इसकी मदद से, फ़्रंटएंड व्यू में बदलाव किए बिना ही, ऐप्लिकेशन के यूज़र इंटरफ़ेस (यूआई) को रेंडर किया जा सकता है. इस शब्दावली को समझने के लिए कुछ जानकारी की ज़रूरत है. हालांकि, आपके ऐप्लिकेशन के डिज़ाइन के लिए इसके असर को समझना ज़रूरी है.
डिक्लेरेटिव प्रोग्रामिंग पैराडाइम
पहले, Android व्यू हैरारकी को यूज़र इंटरफ़ेस (यूआई) विजेट के ट्री के तौर पर दिखाया जाता था. उपयोगकर्ता के इंटरैक्शन जैसी चीज़ों की वजह से, ऐप्लिकेशन की स्थिति बदलती है. इसलिए, मौजूदा डेटा दिखाने के लिए यूज़र इंटरफ़ेस (यूआई) की हैरारकी को अपडेट करना ज़रूरी है.
यूज़र इंटरफ़ेस (यूआई) को अपडेट करने का सबसे आम तरीका है, findViewById() जैसे फ़ंक्शन का इस्तेमाल करके ट्री को एक्सप्लोर करना. साथ ही, button.setText(String), container.addChild(View) या img.setImageBitmap(Bitmap) जैसे तरीकों को कॉल करके नोड बदलना. ये तरीके, विजेट की अंदरूनी स्थिति को बदलते हैं.
व्यू को मैन्युअल तरीके से मैनेज करने पर, गड़बड़ियों की संभावना बढ़ जाती है. अगर डेटा का कोई हिस्सा कई जगहों पर रेंडर किया जाता है, तो हो सकता है कि आप उसे दिखाने वाले किसी व्यू को अपडेट करना भूल जाएं. इसकी वजह से, गैर-कानूनी स्थितियां भी पैदा हो सकती हैं. ऐसा तब होता है, जब दो अपडेट के बीच अचानक कोई विरोध होता है. उदाहरण के लिए, हो सकता है कि कोई अपडेट, यूज़र इंटरफ़ेस (यूआई) से हटाए गए किसी नोड की वैल्यू सेट करने की कोशिश करे. आम तौर पर, सॉफ़्टवेयर के रखरखाव की जटिलता, अपडेट किए जाने वाले व्यू की संख्या के साथ बढ़ती है.
पिछले कुछ सालों में, पूरी इंडस्ट्री डिक्लेरेटिव यूज़र इंटरफ़ेस (यूआई) मॉडल पर शिफ़्ट होने लगी है. इससे यूज़र इंटरफ़ेस बनाना और उन्हें अपडेट करना आसान हो जाता है.
यह तकनीक, पूरी स्क्रीन को फिर से जनरेट करती है. इसके बाद, सिर्फ़ ज़रूरी बदलाव लागू करती है. इस तरीके से, स्टेटफ़ुल व्यू हैरारकी को मैन्युअल तरीके से अपडेट करने की जटिलता से बचा जा सकता है. Compose, डिक्लेरेटिव यूज़र इंटरफ़ेस (यूआई) फ़्रेमवर्क है.
पूरी स्क्रीन को फिर से जनरेट करने में एक समस्या यह है कि इसमें समय, कंप्यूटिंग पावर, और बैटरी का ज़्यादा इस्तेमाल हो सकता है. इस लागत को कम करने के लिए, Compose समझदारी से यह चुनता है कि यूज़र इंटरफ़ेस (यूआई) के किन हिस्सों को किसी भी समय फिर से ड्रॉ करने की ज़रूरत है. इससे आपके यूज़र इंटरफ़ेस (यूआई) कॉम्पोनेंट के डिज़ाइन पर कुछ असर पड़ता है. इस बारे में फिर से कॉम्पोज़ करने वाले सेक्शन में बताया गया है.
कंपोज़ेबल फ़ंक्शन का एक उदाहरण
Compose का इस्तेमाल करके, यूज़र इंटरफ़ेस बनाया जा सकता है. इसके लिए, आपको कंपोज़ेबल फ़ंक्शन का एक सेट तय करना होगा. ये फ़ंक्शन, डेटा लेते हैं और यूज़र इंटरफ़ेस (यूआई) एलिमेंट दिखाते हैं. इसका एक उदाहरण है Greeting विजेट, जो String को लेता है और Text विजेट को दिखाता है. यह विजेट, वेलकम मैसेज दिखाता है.
इस फ़ंक्शन के बारे में ध्यान देने लायक कुछ बातें:
- एनोटेशन: फ़ंक्शन को
@Composableएनोटेशन के साथ एनोटेट किया गया है. ऐप्लिकेशन बनाने की सुविधा वाले सभी फ़ंक्शन में यह एनोटेशन होना चाहिए. यह एनोटेशन, Compose कंपाइलर को बताता है कि इस फ़ंक्शन का मकसद डेटा को यूज़र इंटरफ़ेस (यूआई) में बदलना है. - डेटा इनपुट: फ़ंक्शन, डेटा को इनपुट के तौर पर लेता है. ऐप्लिकेशन बनाने की सुविधा, पैरामीटर स्वीकार कर सकती है. इससे ऐप्लिकेशन का लॉजिक, यूज़र इंटरफ़ेस (यूआई) के बारे में बता सकता है. इस मामले में, हमारा विजेट
Stringको स्वीकार करता है, ताकि वह उपयोगकर्ता का नाम लेकर उसका स्वागत कर सके. - यूज़र इंटरफ़ेस (यूआई) डिसप्ले: यह फ़ंक्शन, यूज़र इंटरफ़ेस (यूआई) में टेक्स्ट दिखाता है. इसके लिए, यह
Text()कंपोज़ेबल फ़ंक्शन को कॉल करता है. यह फ़ंक्शन, टेक्स्ट यूज़र इंटरफ़ेस (यूआई) एलिमेंट बनाता है. ऐप्लिकेशन बनाने की सुविधा, अन्य कंपोज़ेबल फ़ंक्शन को कॉल करके यूज़र इंटरफ़ेस (यूआई) की हैरारकी दिखाती है. - कोई वैल्यू नहीं मिलती: फ़ंक्शन से कोई वैल्यू नहीं मिलती. यूज़र इंटरफ़ेस (यूआई) दिखाने वाले Compose फ़ंक्शन को कुछ भी दिखाने की ज़रूरत नहीं होती. ऐसा इसलिए, क्योंकि वे यूज़र इंटरफ़ेस (यूआई) विजेट बनाने के बजाय, टारगेट स्क्रीन की स्थिति के बारे में बताते हैं.
प्रॉपर्टी: यह फ़ंक्शन तेज़ी से काम करता है, आइडमपोटेंट है, और इसके कोई खराब असर नहीं होते.
- एक ही आर्ग्युमेंट के साथ कई बार कॉल किए जाने पर, फ़ंक्शन एक ही तरह से काम करता है. साथ ही, यह ग्लोबल वैरिएबल या
random()को कॉल करने जैसी अन्य वैल्यू का इस्तेमाल नहीं करता. - यह फ़ंक्शन, यूज़र इंटरफ़ेस (यूआई) के बारे में बताता है. इसमें प्रॉपर्टी या ग्लोबल वैरिएबल में बदलाव करने जैसे कोई खराब असर नहीं होते.
आम तौर पर, ऐप्लिकेशन बनाने की सुविधा वाले सभी फ़ंक्शन इन प्रॉपर्टी के साथ लिखे जाने चाहिए. इसकी वजहें, फिर से कंपोज़ करना लेख में बताई गई हैं.
- एक ही आर्ग्युमेंट के साथ कई बार कॉल किए जाने पर, फ़ंक्शन एक ही तरह से काम करता है. साथ ही, यह ग्लोबल वैरिएबल या
डिक्लेरेटिव पैराडाइम शिफ़्ट
ऑब्जेक्ट-ओरिएंटेड यूज़र इंटरफ़ेस (यूआई) टूलकिट की मदद से, विजेट के ट्री को इंस्टैंशिएट करके यूज़र इंटरफ़ेस (यूआई) को शुरू किया जाता है. आम तौर पर, ऐसा एक्सएमएल लेआउट फ़ाइल को इनफ़्लेट करके किया जाता है. हर विजेट अपनी इंटरनल स्टेट को बनाए रखता है. साथ ही, गेटर और सेटर मेथड को एक्सपोज़ करता है. इससे ऐप्लिकेशन लॉजिक, विजेट के साथ इंटरैक्ट कर पाता है.
Compose के डिक्लेरेटिव तरीके में, विजेट काफ़ी हद तक स्टेटलेस होते हैं. साथ ही, ये सेटर या गेटर फ़ंक्शन को एक्सपोज़ नहीं करते. असल में, विजेट को ऑब्जेक्ट के तौर पर नहीं दिखाया जाता.
यूज़र इंटरफ़ेस (यूआई) को अपडेट करने के लिए, अलग-अलग आर्ग्युमेंट के साथ एक ही कंपोज़ेबल फ़ंक्शन को कॉल किया जाता है. इससे आर्किटेक्चरल पैटर्न को स्टेट उपलब्ध कराना आसान हो जाता है. जैसे, ViewModel. इसके बारे में ऐप्लिकेशन आर्किटेक्चर की गाइड में बताया गया है. इसके बाद, आपके कंपोज़ेबल, मॉनिटर किए जा सकने वाले डेटा के अपडेट होने पर, ऐप्लिकेशन की मौजूदा स्थिति को यूज़र इंटरफ़ेस (यूआई) में बदलने के लिए ज़िम्मेदार होते हैं.
जब उपयोगकर्ता यूज़र इंटरफ़ेस (यूआई) से इंटरैक्ट करता है, तो यूआई onClick जैसे इवेंट ट्रिगर करता है.
इन इवेंट से, ऐप्लिकेशन लॉजिक को सूचना मिलनी चाहिए. इससे ऐप्लिकेशन की स्थिति में बदलाव किया जा सकता है.
स्थिति बदलने पर, ऐप्लिकेशन बनाने की सुविधा को नए डेटा के साथ फिर से कॉल किया जाता है. इस वजह से, यूज़र इंटरफ़ेस (यूआई) एलिमेंट फिर से बनाए जाते हैं. इस प्रोसेस को रीकंपोज़िशन कहा जाता है.
लगातार अपडेट होने वाली जानकारी
कंपोज़ेबल फ़ंक्शन, एक्सएमएल के बजाय Kotlin में लिखे जाते हैं. इसलिए, वे Kotlin के किसी भी अन्य कोड की तरह डाइनैमिक हो सकते हैं. उदाहरण के लिए, मान लें कि आपको ऐसा यूज़र इंटरफ़ेस (यूआई) बनाना है जो उपयोगकर्ताओं की सूची का स्वागत करता है:
@Composable fun Greeting(names: List<String>) { for (name in names) { Text("Hello $name") } }
यह फ़ंक्शन, नामों की सूची लेता है और हर उपयोगकर्ता के लिए एक ग्रीटिंग जनरेट करता है.
ऐप्लिकेशन बनाने की सुविधा काफ़ी बेहतर हो सकती है. if स्टेटमेंट का इस्तेमाल करके, यह तय किया जा सकता है कि आपको कोई यूज़र इंटरफ़ेस (यूआई) एलिमेंट दिखाना है या नहीं. लूप का इस्तेमाल किया जा सकता है. हेल्पर फ़ंक्शन को कॉल किया जा सकता है. आपके पास, प्रोग्रामिंग लैंग्वेज की सभी सुविधाओं का इस्तेमाल करने की सुविधा होती है.
Jetpack Compose का एक मुख्य फ़ायदा यह है कि इसमें कई तरह की सुविधाएं मिलती हैं और इसे आसानी से इस्तेमाल किया जा सकता है.
दोबारा कंपोज़ करने की प्रोसेस
इंपरेटिव यूज़र इंटरफ़ेस (यूआई) मॉडल में, किसी विजेट को बदलने के लिए, विजेट पर सेटर को कॉल किया जाता है, ताकि उसकी इंटरनल स्टेट को बदला जा सके. Compose में, नए डेटा के साथ ऐप्लिकेशन बनाने की सुविधा को फिर से कॉल किया जाता है. ऐसा करने से, फ़ंक्शन फिर से कंपोज़ हो जाता है. इसका मतलब है कि फ़ंक्शन से जनरेट किए गए विजेट, ज़रूरत पड़ने पर नए डेटा के साथ फिर से बनाए जाते हैं. Compose फ़्रेमवर्क, सिर्फ़ उन कॉम्पोनेंट को फिर से कंपोज़ कर सकता है जिनमें बदलाव हुआ है.
उदाहरण के लिए, ऐप्लिकेशन बनाने की इस सुविधा को देखें, जो एक बटन दिखाती है:
@Composable fun ClickCounter(clicks: Int, onClick: () -> Unit) { Button(onClick = onClick) { Text("I've been clicked $clicks times") } }
हर बार बटन पर क्लिक करने पर, कॉलर clicks की वैल्यू अपडेट करता है.
Compose, नई वैल्यू दिखाने के लिए, Text फ़ंक्शन के साथ लैम्ब्डा को फिर से कॉल करता है. इस प्रोसेस को रीकंपोज़िशन कहा जाता है. वैल्यू पर निर्भर न करने वाले अन्य फ़ंक्शन फिर से कंपोज़ नहीं किए जाते.
जैसा कि हमने बताया, पूरे यूज़र इंटरफ़ेस (यूआई) ट्री को फिर से कंपोज़ करने में, कंप्यूटेशनल पावर और बैटरी लाइफ़ का ज़्यादा इस्तेमाल हो सकता है. Compose, इंटेलिजेंट रीकंपोज़िशन की मदद से इस समस्या को हल करता है.
इनपुट बदलने पर, ऐप्लिकेशन बनाने की सुविधा को फिर से कॉल करने की प्रोसेस को रीकंपोज़िशन कहते हैं. जब Compose नए इनपुट के आधार पर फिर से कंपोज़ करता है, तो यह सिर्फ़ उन फ़ंक्शन या लैम्ब्डा को कॉल करता है जिनमें बदलाव हुआ हो. बाकी फ़ंक्शन या लैम्ब्डा को छोड़ देता है. जिन फ़ंक्शन या लैम्ब्डा के पैरामीटर में कोई बदलाव नहीं हुआ है उन्हें स्किप करके, Compose बेहतर तरीके से रीकंपोज़ करता है.
कंपोज़ेबल फ़ंक्शन को लागू करने से होने वाले साइड-इफ़ेक्ट पर कभी भी भरोसा न करें. ऐसा इसलिए, क्योंकि किसी फ़ंक्शन के रिकॉम्पोज़िशन को छोड़ा जा सकता है. अगर ऐसा किया जाता है, तो हो सकता है कि उपयोगकर्ताओं को आपके ऐप्लिकेशन में अजीब और अनचाहा व्यवहार देखने को मिले. खराब असर, ऐसा कोई भी बदलाव होता है जो आपके ऐप्लिकेशन के बाकी हिस्सों में दिखता है. उदाहरण के लिए, ये सभी कार्रवाइयां खतरनाक खराब असर हैं:
- शेयर किए गए ऑब्जेक्ट की प्रॉपर्टी में लिखना
ViewModelमें ऑब्ज़र्वेबल को अपडेट करना- शेयर की गई प्राथमिकताएं अपडेट करना
ऐप्लिकेशन बनाने की सुविधा को हर फ़्रेम के लिए फिर से लागू किया जा सकता है. जैसे, जब कोई ऐनिमेशन रेंडर किया जा रहा हो. ऐप्लिकेशन बनाने की सुविधा को तेज़ी से काम करना चाहिए, ताकि ऐनिमेशन के दौरान रुकावट न आए. अगर आपको ज़्यादा रिसॉर्स खर्च करने वाले काम करने हैं, जैसे कि शेयर की गई सेटिंग से डेटा पढ़ना, तो उन्हें बैकग्राउंड कोरूटीन में करें. इसके बाद, वैल्यू के नतीजे को पैरामीटर के तौर पर, ऐप्लिकेशन बनाने की सुविधा को पास करें.
उदाहरण के लिए, यह कोड SharedPreferences में किसी वैल्यू को अपडेट करने के लिए, एक कंपोज़ेबल बनाता है. कंपोज़ेबल को शेयर की गई सेटिंग से, खुद ही डेटा को पढ़ने या लिखने की अनुमति नहीं होनी चाहिए. इसके बजाय, यह कोड, बैकग्राउंड कोरूटीन में ViewModel पर रीड और राइट को मूव करता है. ऐप्लिकेशन लॉजिक, अपडेट को ट्रिगर करने के लिए कॉलबैक के साथ मौजूदा वैल्यू को पास करता है.
@Composable fun SharedPrefsToggle( text: String, value: Boolean, onValueChanged: (Boolean) -> Unit ) { Row { Text(text) Checkbox(checked = value, onCheckedChange = onValueChanged) } }
इस दस्तावेज़ में, Compose का इस्तेमाल करते समय ध्यान रखने वाली कई बातों के बारे में बताया गया है:
- रीकंपोज़िशन की प्रोसेस में, ऐप्लिकेशन बनाने की सुविधा और लैम्ब्डा फ़ंक्शन को ज़्यादा से ज़्यादा स्किप किया जाता है.
- रीकंपोज़िशन ऑप्टिमिस्टिक होता है और इसे रद्द किया जा सकता है.
- ऐप्लिकेशन बनाने की सुविधा को बार-बार चलाया जा सकता है. जैसे, किसी ऐनिमेशन के हर फ़्रेम के लिए.
- कंपोज़ेबल फ़ंक्शन एक साथ काम कर सकते हैं.
- कंपोज़ेबल फ़ंक्शन किसी भी क्रम में लागू हो सकते हैं.
यहां दिए गए सेक्शन में, ऐप्लिकेशन बनाने की सुविधा को फिर से कंपोज़ करने के लिए, उसे बनाने का तरीका बताया गया है. हर मामले में, सबसे सही तरीका यह है कि ऐप्लिकेशन बनाने की सुविधा को तेज़, आइडेंपोटेंट, और खराब असर से मुक्त रखा जाए.
रीकंपोज़िशन की प्रोसेस को ज़्यादा से ज़्यादा स्किप किया जाता है
जब आपके यूज़र इंटरफ़ेस (यूआई) के कुछ हिस्से अमान्य होते हैं, तो Compose सिर्फ़ उन हिस्सों को फिर से कंपोज़ करने की पूरी कोशिश करता है जिन्हें अपडेट करने की ज़रूरत होती है. इसका मतलब है कि यह यूज़र इंटरफ़ेस (यूआई) ट्री में, ऊपर या नीचे मौजूद किसी भी कंपोज़ेबल को लागू किए बिना, किसी एक Button के कंपोज़ेबल को फिर से चलाने से बच सकता है.
हर कंपोज़ेबल फ़ंक्शन और लैम्ब्डा, अपने-आप फिर से कंपोज़ हो सकता है. यहां दिए गए उदाहरण में बताया गया है कि सूची को रेंडर करते समय, रीकंपोज़िशन की प्रोसेस कुछ एलिमेंट को कैसे छोड़ सकती है:
/** * Display a list of names the user can click with a header */ @Composable fun NamePicker( header: String, names: List<String>, onNameClicked: (String) -> Unit ) { Column { // this will recompose when [header] changes, but not when [names] changes Text(header, style = MaterialTheme.typography.bodyLarge) HorizontalDivider() // LazyColumn is the Compose version of a RecyclerView. // The lambda passed to items() is similar to a RecyclerView.ViewHolder. LazyColumn { items(names) { name -> // When an item's [name] updates, the adapter for that item // will recompose. This will not recompose when [header] changes NamePickerItem(name, onNameClicked) } } } } /** * Display a single name the user can click. */ @Composable private fun NamePickerItem(name: String, onClicked: (String) -> Unit) { Text(name, Modifier.clickable(onClick = { onClicked(name) })) }
इनमें से हर स्कोप, रीकंपोज़िशन के दौरान लागू होने वाली एकमात्र चीज़ हो सकती है.
header में बदलाव होने पर, Compose अपने किसी भी पैरंट को लागू किए बिना, Column लैम्डा पर जा सकता है. Column को लागू करते समय, अगर names में कोई बदलाव नहीं हुआ है, तो Compose, LazyColumn के आइटम को स्किप कर सकता है.
यह भी ध्यान रखें कि कंपोज़ किए जा सकने वाले सभी फ़ंक्शन या लैम्ब्डा फ़ंक्शन, खराब असर से मुक्त होने चाहिए. जब आपको कोई साइड-इफ़ेक्ट करना हो, तो उसे कॉलबैक से ट्रिगर करें.
रीकंपोज़िशन ऑप्टिमिस्टिक है
जब भी Compose को लगता है कि किसी कंपोज़ेबल के पैरामीटर बदल गए हैं, तो रीकंपोज़िशन शुरू हो जाता है. रीकंपोज़िशन ऑप्टिमिस्टिक होता है. इसका मतलब है कि Compose को उम्मीद होती है कि पैरामीटर फिर से बदलने से पहले,रीकंपोज़िशन पूरा हो जाएगा. अगर रीकंपोज़िशन की प्रोसेस पूरी होने से पहले कोई पैरामीटर बदल जाता है, तो Compose, रीकंपोज़िशन की प्रोसेस को रद्द कर सकता है. साथ ही, नए पैरामीटर के साथ इसे फिर से शुरू कर सकता है.
रीकंपोज़िशन रद्द होने पर, Compose रीकंपोज़िशन से यूज़र इंटरफ़ेस (यूआई) ट्री को खारिज कर देता है. अगर आपके पास कोई ऐसा खराब असर है जो यूज़र इंटरफ़ेस (यूआई) पर निर्भर करता है, तो कंपोज़िशन रद्द होने पर भी खराब असर लागू होगा. इससे ऐप्लिकेशन की स्थिति में अंतर आ सकता है.
पुष्टि करें कि सभी कंपोज़ेबल फ़ंक्शन और लैम्ब्डा, आइडेंपोटेंट हों और उनमें कोई खराब असर न हो, ताकि ऑप्टिमिस्टिक रीकंपोज़िशन को मैनेज किया जा सके.
ऐप्लिकेशन बनाने की सुविधा का इस्तेमाल अक्सर किया जा सकता है
कुछ मामलों में, यूज़र इंटरफ़ेस (यूआई) ऐनिमेशन के हर फ़्रेम के लिए, ऐप्लिकेशन बनाने की सुविधा को चलाया जा सकता है. अगर फ़ंक्शन, डिवाइस के स्टोरेज से डेटा पढ़ने जैसी ज़्यादा मेमोरी खर्च करने वाली कार्रवाइयां करता है, तो इससे यूज़र इंटरफ़ेस (यूआई) में रुकावट आ सकती है.
उदाहरण के लिए, अगर आपका विजेट डिवाइस की सेटिंग को पढ़ने की कोशिश करता है, तो हो सकता है कि वह उन सेटिंग को एक सेकंड में सैकड़ों बार पढ़े. इससे आपके ऐप्लिकेशन की परफ़ॉर्मेंस पर बुरा असर पड़ सकता है.
अगर ऐप्लिकेशन बनाने की सुविधा को डेटा की ज़रूरत है, तो उस डेटा के लिए पैरामीटर तय करें. इसके बाद, ज़्यादा समय लेने वाले काम को कंपोज़िशन के बाहर किसी दूसरे थ्रेड में ले जाया जा सकता है. साथ ही, mutableStateOf या LiveData का इस्तेमाल करके, नतीजे के तौर पर मिली वैल्यू को पैरामीटर के तौर पर, ऐप्लिकेशन बनाने की सुविधा में पास किया जा सकता है.
ऐप्लिकेशन बनाने की सुविधा को एक साथ चलाया जा सकता है
Compose, कंपोज़ किए जा सकने वाले फ़ंक्शन को एक साथ चलाकर, फिर से कंपोज़ करने की प्रोसेस को ऑप्टिमाइज़ कर सकता है. इससे Compose, कई कोर का फ़ायदा ले पाएगा. साथ ही, स्क्रीन पर न दिखने वाले कंपोज़ेबल फ़ंक्शन को कम प्राथमिकता पर चला पाएगा.
इस ऑप्टिमाइज़ेशन का मतलब है कि ऐप्लिकेशन बनाने की सुविधा, बैकग्राउंड थ्रेड के पूल में काम कर सकती है.
अगर ऐप्लिकेशन बनाने की सुविधा, ViewModel पर किसी फ़ंक्शन को कॉल करती है, तो Compose उस फ़ंक्शन को एक ही समय पर कई थ्रेड से कॉल कर सकता है.
यह पुष्टि करने के लिए कि आपका ऐप्लिकेशन सही तरीके से काम कर रहा है, कंपोज़ेबल फ़ंक्शन का कोई खराब असर नहीं होना चाहिए. इसके बजाय, onClick जैसे कॉलबैक से साइड-इफ़ेक्ट ट्रिगर करें. ये हमेशा यूज़र इंटरफ़ेस (यूआई) थ्रेड पर लागू होते हैं.
जब किसी कंपोज़ेबल फ़ंक्शन को शुरू किया जाता है, तो हो सकता है कि वह कॉलर से अलग थ्रेड पर शुरू हो. इसका मतलब है कि कंपोज़ेबल लैम्डा में वैरिएबल में बदलाव करने वाले कोड से बचना चाहिए. ऐसा इसलिए, क्योंकि ऐसा कोड थ्रेड-सेफ़ नहीं होता और यह कंपोज़ेबल लैम्डा का एक ऐसा खराब असर है जिसकी अनुमति नहीं है.
यहां एक उदाहरण दिया गया है, जिसमें एक सूची और उसकी संख्या दिखाने वाला कंपोज़ेबल दिखाया गया है:
@Composable fun ListComposable(myList: List<String>) { Row(horizontalArrangement = Arrangement.SpaceBetween) { Column { for (item in myList) { Text("Item: $item") } } Text("Count: ${myList.size}") } }
इस कोड का कोई खराब असर नहीं होता. साथ ही, यह इनपुट सूची को यूज़र इंटरफ़ेस (यूआई) में बदल देता है. यह छोटी सूची दिखाने के लिए बेहतरीन कोड है. हालांकि, अगर फ़ंक्शन किसी लोकल वैरिएबल में लिखता है, तो यह कोड थ्रेड-सेफ़ या सही नहीं होगा:
@Composable fun ListWithBug(myList: List<String>) { var items = 0 Row(horizontalArrangement = Arrangement.SpaceBetween) { Column { for (item in myList) { Card { Text("Item: $item") items++ // Avoid! Side-effect of the column recomposing. } } } Text("Count: $items") } }
इस उदाहरण में, हर बार रीकंपोज़िशन होने पर items में बदलाव किया जाता है. यह ऐनिमेशन का हर फ़्रेम हो सकता है या सूची के अपडेट होने पर हो सकता है. दोनों ही मामलों में, यूज़र इंटरफ़ेस (यूआई) में
गलत संख्या दिखेगी. इस वजह से, Compose में इस तरह के राइट इस्तेमाल नहीं किए जा सकते. इन राइट पर पाबंदी लगाकर, हम फ़्रेमवर्क को थ्रेड बदलने की अनुमति देते हैं, ताकि कंपोज़ेबल लैम्डा को लागू किया जा सके.
कंपोज़ेबल फ़ंक्शन किसी भी क्रम में लागू हो सकते हैं
अगर आपने कंपोज़ेबल फ़ंक्शन का कोड देखा है, तो आपको लग सकता है कि कोड उसी क्रम में चलता है जिस क्रम में वह दिखता है. हालांकि, ऐसा होना ज़रूरी नहीं है. अगर किसी composable फ़ंक्शन में अन्य composable फ़ंक्शन के कॉल शामिल हैं, तो वे फ़ंक्शन किसी भी क्रम में चल सकते हैं. Compose में यह पहचानने का विकल्प होता है कि कुछ यूज़र इंटरफ़ेस (यूआई) एलिमेंट को अन्य एलिमेंट की तुलना में ज़्यादा प्राथमिकता दी जाए और उन्हें पहले ड्रॉ किया जाए.
उदाहरण के लिए, मान लें कि आपके पास टैब लेआउट में तीन स्क्रीन बनाने के लिए, इस तरह का कोड है:
@Composable fun ButtonRow() { MyFancyNavigation { StartScreen() MiddleScreen() EndScreen() } }
StartScreen, MiddleScreen, और EndScreen को किसी भी क्रम में कॉल किया जा सकता है. इसका मतलब है कि आपके पास, उदाहरण के लिए, StartScreen() को कोई ग्लोबल वैरिएबल (एक खराब असर) सेट करने और MiddleScreen() को उस बदलाव का फ़ायदा लेने की अनुमति नहीं है. इसके बजाय, हर फ़ंक्शन को अपने-आप में पूरा होना चाहिए.
ज़्यादा जानें
Compose और ऐप्लिकेशन बनाने की सुविधा के बारे में ज़्यादा जानने के लिए, यहां दिए गए अन्य संसाधन देखें.
वीडियो
आपके लिए सुझाव
- ध्यान दें: JavaScript बंद होने पर, लिंक टेक्स्ट दिखता है
- Jetpack Compose के लिए Kotlin
- स्टेट और Jetpack Compose
- Jetpack Compose का आर्किटेक्चरल लेयरिंग