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()
को कॉल करने जैसी अन्य वैल्यू का इस्तेमाल नहीं करता है. - यह फ़ंक्शन, यूज़र इंटरफ़ेस (यूआई) के बारे में बताता है. इससे कोई साइड इफ़ेक्ट नहीं होता. जैसे, प्रॉपर्टी या ग्लोबल वैरिएबल में बदलाव करना.
आम तौर पर, सभी कंपोज़ेबल फ़ंक्शन को इन प्रॉपर्टी के साथ लिखा जाना चाहिए. इसकी वजह रीकंपोज़िशन में बताई गई है.
- एक ही आर्ग्युमेंट के साथ कई बार कॉल किए जाने पर, फ़ंक्शन एक जैसा काम करता है. साथ ही, यह ग्लोबल वैरिएबल या
डिक्लेरेटिव पैराडाइम में बदलाव
कई ज़रूरी ऑब्जेक्ट-ओरिएंटेड यूज़र इंटरफ़ेस (यूआई) टूलकिट में, विजेट के ट्री को इंस्टैंटिएट करके यूआई को शुरू किया जाता है. आम तौर पर, ऐसा एक्सएमएल लेआउट फ़ाइल को बड़ा करके किया जाता है. हर विजेट अपनी इंटरनल स्थिति बनाए रखता है. साथ ही, यह getter और setter के ऐसे तरीके दिखाता है जिनकी मदद से ऐप्लिकेशन लॉजिक, विजेट के साथ इंटरैक्ट कर सकता है.
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
's कंपोज़ेबल को फिर से चलाने के लिए स्किप कर सकता है.
हर कंपोज़ेबल फ़ंक्शन और लैम्डा, खुद से रीकंपोज़ हो सकता है. यहां दिए गए उदाहरण में बताया गया है कि सूची रेंडर करते समय, रीकंपोज़िशन कुछ एलिमेंट को कैसे छोड़ सकता है:
/** * 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
lambda पर जा सकता है. इसके अलावा, Column
को लागू करते समय, Compose LazyColumn
के आइटम को स्किप कर सकता है. ऐसा तब होता है, जब names
में कोई बदलाव नहीं होता.
साथ ही, सभी कंपोज़ेबल फ़ंक्शन या लैम्डा में साइड इफ़ेक्ट नहीं होना चाहिए. जब आपको कोई साइड-इफ़ेक्ट लागू करना हो, तो उसे कॉलबैक से ट्रिगर करें.
रीकंपोज़िशन ऑप्टिमिस्टिक है
जब भी 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 में इस तरह के राइट ऑपरेशन काम नहीं करते. इन राइट ऑपरेशन को ब्लॉक करके, हम फ़्रेमवर्क को थ्रेड बदलने की अनुमति देते हैं, ताकि कंपोज़ेबल लैम्डा को लागू किया जा सके.
ऐप्लिकेशन बनाने की सुविधा वाले फ़ंक्शन किसी भी क्रम में लागू किए जा सकते हैं
अगर कंपोज़ेबल फ़ंक्शन के कोड को देखा जाए, तो आपको लग सकता है कि कोड उसी क्रम में चलता है जिस क्रम में वह दिखता है. हालांकि, यह ज़रूरी नहीं कि यह जानकारी सही हो. अगर किसी कंपोज़ेबल फ़ंक्शन में अन्य कंपोज़ेबल फ़ंक्शन को कॉल किया जाता है, तो वे फ़ंक्शन किसी भी क्रम में चल सकते हैं. Compose में यह सुविधा होती है कि वह कुछ यूज़र इंटरफ़ेस (यूआई) एलिमेंट को दूसरों के मुकाबले ज़्यादा प्राथमिकता दे सकता है और उन्हें पहले दिखा सकता है.
उदाहरण के लिए, मान लें कि आपके पास टैब लेआउट में तीन स्क्रीन बनाने के लिए, इस तरह का कोड है:
@Composable fun ButtonRow() { MyFancyNavigation { StartScreen() MiddleScreen() EndScreen() } }
StartScreen
, MiddleScreen
, और EndScreen
को कॉल किसी भी क्रम में किए जा सकते हैं. इसका मतलब है कि उदाहरण के लिए, StartScreen()
कुछ ग्लोबल वैरिएबल (साइड इफ़ेक्ट) सेट नहीं कर सकता और MiddleScreen()
उस बदलाव का फ़ायदा नहीं ले सकता. इसके बजाय, उन सभी फ़ंक्शन में ज़रूरी जानकारी होनी चाहिए.
ज़्यादा जानें
Compose और कंपोज़ेबल फ़ंक्शन के बारे में ज़्यादा जानने के लिए, यहां दिए गए अतिरिक्त संसाधन देखें.
वीडियो
आपके लिए सुझाव
- ध्यान दें: JavaScript बंद होने पर लिंक टेक्स्ट दिखता है
- Jetpack Compose के लिए Kotlin
- स्टेट और Jetpack Compose
- Jetpack Compose के आर्किटेक्चर की लेयरिंग