इस पेज पर, आपको कॉम्पोज़ेबल के लाइफ़साइकल के बारे में जानकारी मिलेगी. साथ ही, यह भी पता चलेगा कि Compose यह कैसे तय करता है कि कॉम्पोज़ेबल को फिर से कॉम्पोज़ करने की ज़रूरत है या नहीं.
लाइफ़साइकल की खास जानकारी
जैसा कि मैनेजिंग स्टेट दस्तावेज़ में बताया गया है, कंपोज़िशन से आपके ऐप्लिकेशन के यूज़र इंटरफ़ेस (यूआई) की जानकारी मिलती है. इसे कंपोज़ेबल चलाकर तैयार किया जाता है. कंपोज़ेबल, कंपोज़ेबल का ट्री स्ट्रक्चर होता है, जो आपके यूज़र इंटरफ़ेस (यूआई) के बारे में बताता है.
जब Jetpack Compose आपके कॉम्पोज़ेबल को पहली बार चलाएगा, तो शुरुआती कॉम्पोज़िशन के दौरान, वह उन कॉम्पोज़ेबल को ट्रैक करेगा जिन्हें आपने कॉम्पोज़िशन में अपने यूज़र इंटरफ़ेस (यूआई) के बारे में बताने के लिए कॉल किया है. इसके बाद, आपके ऐप्लिकेशन की स्थिति में बदलाव होने पर, Jetpack शेड्यूल को फिर से बनाने के लिए लिखें. रीकंपोज़िशन तब होता है, जब Jetpack Compose उन कॉम्पोज़ेबल को फिर से लागू करता है जो स्टेटस में हुए बदलावों की वजह से बदल सकते हैं. इसके बाद, किसी भी बदलाव को दिखाने के लिए कॉम्पोज़िशन को अपडेट करता है.
कंपोज़िशन को सिर्फ़ शुरुआती कंपोज़िशन के ज़रिए बनाया जा सकता है और इसे शॉर्ट वीडियो में बदलाव करना. कॉम्पोज़िशन में बदलाव करने का एकमात्र तरीका, उसे फिर से कॉम्पोज़ करना है.
पहला डायग्राम. कॉम्पोज़िशन में किसी कॉम्पोज़ेबल की लाइफ़साइकल. यह कंपोज़िशन में शामिल होता है, शून्य या उससे ज़्यादा बार फिर से कंपोज़ किया जाता है, और कंपोज़िशन से बाहर निकल जाता है.
आम तौर पर, State<T>
ऑब्जेक्ट में बदलाव होने पर, फिर से कॉम्पोज़ करने की प्रोसेस शुरू होती है. लिखें
इन्हें ट्रैक करता है और कंपोज़ेबल में चलता है
खास State<T>
और कोई भी कंपोज़ेबल जिसे कॉल किया जा सकता हो
स्किप किया.
अगर किसी कंपोज़ेबल को कई बार कॉल किया जाता है, तो कंपोज़िशन. कंपोज़िशन में हर कॉल का अपना लाइफ़साइकल होता है.
@Composable fun MyComposable() { Column { Text("Hello") Text("World") } }
दूसरी इमेज. कंपोज़िशन में MyComposable
का रेप्रज़ेंटेशन. अगर किसी कॉम्पोज़ेबल को कई बार कॉल किया जाता है, तो कंपोज़िशन में कई इंस्टेंस डाले जाते हैं. किसी एलिमेंट का रंग अलग होने का मतलब है कि वह एलिमेंट
अलग करें.
कंपोज़िशन में मौजूद, कॉम्पोज़ेबल की बनावट
कॉम्पोज़िशन में किसी कॉम्पोज़ेबल के इंस्टेंस की पहचान, उसकी कॉल साइट से की जाती है. Compose कंपाइलर हर कॉल साइट को अलग मानता है. कॉल के लिए कंपोज़ेबल कई कॉल साइटों से, कंपोज़ेबल के कई इंस्टेंस कंपोज़िशन.
अगर डिज़ाइन करते समय, कंपोज़ेबल कॉल किया जाता है और वे पहले के मुकाबले अलग-अलग कंपोज़ेबल कॉल करते हैं पिछली कंपोज़ेबल में बनाए गए कौन-कौनसे कंपोज़ेबल थे कॉल किया गया या कॉल नहीं किया गया और उन कंपोज़ेबल के लिए जिन्हें दोनों भाषाओं में कॉल किया गया कंपोज़िशन इस्तेमाल नहीं किया है, तो कंपोज़िशन में इन्हें दोबारा नहीं डाला जाएगा. ऐसा तब होगा, जब उनके इनपुट में ऐसा न हो बदला गया.
साइड इफ़ेक्ट को उनके कॉम्पोज़ेबल से जोड़ने के लिए, पहचान को बनाए रखना ज़रूरी है, ताकि हर बार फिर से कॉम्पोज़ करने के बजाय, वे सही तरीके से पूरे हो सकें.
नीचे दिया गया उदाहरण देखें:
@Composable fun LoginScreen(showError: Boolean) { if (showError) { LoginError() } LoginInput() // This call site affects where LoginInput is placed in Composition } @Composable fun LoginInput() { /* ... */ } @Composable fun LoginError() { /* ... */ }
ऊपर दिए गए कोड स्निपेट में, LoginScreen
शर्त के साथ
LoginError
कंपोज़ेबल और LoginInput
कंपोज़ेबल को हमेशा कॉल किया जाएगा. हर
कॉल के लिए, एक यूनीक कॉल साइट और सोर्स पोज़िशन चुनी गई है, जिसका इस्तेमाल कंपाइलर
पहचानने में आसानी होती है.
तीसरी इमेज. राज्य के कंपोज़िशन में LoginScreen
का प्रतिनिधित्व
बदलाव होते हैं और एक रीकंपोज़िशन होता है. एक जैसे रंग का मतलब है कि उसे फिर से नहीं बनाया गया है.
भले ही, LoginInput
को पहले कॉल किया गया हो, लेकिन बाद में दूसरा नाम मिला,
LoginInput
इंस्टेंस को बदलाव के दौरान सेव रखा जाएगा. इसके अलावा,
क्योंकि LoginInput
में ऐसा कोई पैरामीटर नहीं है जो बदल गया हो
फिर से लिखें, LoginInput
को किया गया कॉल कंपोज़ से स्किप कर दिया जाएगा.
स्मार्ट रीकंपोज़िशन की सुविधा को बेहतर बनाने के लिए ज़्यादा जानकारी जोड़ना
किसी कॉम्पोज़ेबल को कई बार कॉल करने पर, वह कंपोज़िशन में भी कई बार जुड़ जाएगा. जब किसी कॉल साइट से किसी कॉम्पोज़ेबल को कई बार कॉल किया जाता है, तो Compose के पास उस कॉम्पोज़ेबल के हर कॉल की यूनीक पहचान करने के लिए कोई जानकारी नहीं होती. इसलिए, इंस्टेंस को अलग-अलग रखने के लिए, कॉल साइट के साथ-साथ, लागू करने के क्रम का इस्तेमाल किया जाता है. कभी-कभी यह व्यवहार बेहद ज़रूरी होता है, लेकिन कुछ मामलों में इससे अनचाहा व्यवहार हो सकता है.
@Composable fun MoviesScreen(movies: List<Movie>) { Column { for (movie in movies) { // MovieOverview composables are placed in Composition given its // index position in the for loop MovieOverview(movie) } } }
ऊपर दिए गए उदाहरण में, Compose, कॉल साइट के साथ-साथ, कॉम्पोज़िशन में इंस्टेंस को अलग रखने के लिए, लागू करने के क्रम का इस्तेमाल करता है. अगर कोई नया movie
जोड़ा जाता है
सूची में सबसे नीचे तक लिखने के बाद, आप
सूची में उनकी जगह नहीं बदली है. इसलिए, कंपोज़िशन में
इन इंस्टेंस के लिए movie
इनपुट एक जैसा ही है.
चौथी इमेज. नए कंपोज़िशन में MoviesScreen
को दिखाना
एलिमेंट को सूची में सबसे नीचे जोड़ा गया है. इसमें MovieOverview
कंपोज़ेबल
कंपोज़िशन को फिर से इस्तेमाल किया जा सकता है. MovieOverview
में एक जैसे रंग का मतलब है, कंपोज़ेबल
फिर से नहीं लिखा गया है.
हालांकि, अगर movies
सूची, सबसे ऊपर या
आइटम हटाने या उनका क्रम बदलने से, सूची के बीच में. आइटम को
उन सभी MovieOverview
कॉल में जिनके इनपुट पैरामीटर की स्थिति
सूची. उदाहरण के लिए, अगर MovieOverview
किसी साइड इफ़ेक्ट का इस्तेमाल करके, मूवी इमेज फ़ेच करता है, तो यह काफ़ी ज़रूरी है. अगर इफ़ेक्ट लागू होने के दौरान रीकंपोज़िशन होता है, तो इफ़ेक्ट रद्द हो जाएगा और फिर से शुरू हो जाएगा.
@Composable fun MovieOverview(movie: Movie) { Column { // Side effect explained later in the docs. If MovieOverview // recomposes, while fetching the image is in progress, // it is cancelled and restarted. val image = loadNetworkImage(movie.url) MovieHeader(image) /* ... */ } }
पांचवीं इमेज. सूची में नया एलिमेंट जोड़ने पर, कॉम्पोज़िशन में MoviesScreen
का दिखना. MovieOverview
कॉम्पोज़ेबल का फिर से इस्तेमाल नहीं किया जा सकता और सभी साइड इफ़ेक्ट फिर से शुरू हो जाएंगे. MovieOverview
में अलग रंग का मतलब है कि
कंपोज़ेबल को फिर से तैयार किया गया.
आम तौर पर, हम MovieOverview
इंस्टेंस की पहचान इस तरह समझना चाहते हैं:
को पास किए गए movie
की पहचान से लिंक किया गया होता है. अगर हम फ़िल्मों की सूची का क्रम बदलते हैं, तो हम कॉम्पोज़िशन ट्री में मौजूद इंस्टेंस का क्रम भी इसी तरह बदल देंगे. ऐसा करने के बजाय, हम हर MovieOverview
कॉम्पोज़ेबल को किसी दूसरी फ़िल्म के इंस्टेंस के साथ फिर से कॉम्पोज़ नहीं करेंगे. कंपोज़ की मदद से, रनटाइम के बारे में जानकारी हासिल की जा सकती है
ट्री के किसी हिस्से की पहचान करने के लिए, आपको किन वैल्यू का इस्तेमाल करना है:
key
कंपोज़ेबल.
कोड के एक ब्लॉक को एक या एक से ज़्यादा कंपोज़ेबल में कॉल करके रैप किया जा सकता है
पास की गई वैल्यू शामिल हैं, तो उन वैल्यू को जोड़कर
इंस्टेंस से जुड़े न हों. key
की वैल्यू यह ज़रूरी नहीं है कि
यह पूरी दुनिया में यूनीक है, लेकिन यह सिर्फ़ इसके शुरू होने के विकल्पों में से अलग होना चाहिए
कंपोज़ेबल. इसलिए इस उदाहरण में, प्रत्येक movie
के लिए एक
key
, जो movies
में से अलग है; अगर यह उस key
को
अन्य कंपोज़ेबल.
@Composable fun MoviesScreenWithKey(movies: List<Movie>) { Column { for (movie in movies) { key(movie.id) { // Unique ID for this movie MovieOverview(movie) } } } }
ऊपर बताए गए तरीके से, भले ही सूची में मौजूद एलिमेंट बदल जाएं, Compose MovieOverview
के अलग-अलग कॉल को पहचानता है और उनका फिर से इस्तेमाल कर सकता है.
छठी इमेज. सूची में नया एलिमेंट जोड़ने पर, कॉम्पोज़िशन में MoviesScreen
का दिखना. MovieOverview
कॉम्पोज़ेबल में यूनीक बटन होते हैं. इसलिए, Compose यह पहचान लेता है कि किन MovieOverview
इंस्टेंस में बदलाव नहीं हुआ है और उनका फिर से इस्तेमाल किया जा सकता है. साथ ही, उनके साइड इफ़ेक्ट लागू होते रहेंगे.
कुछ कंपोज़ेबल, key
कंपोज़ेबल के साथ काम करते हैं. उदाहरण के लिए,
LazyColumn
, items
डीएसएल में पसंद के मुताबिक key
तय करने की मंज़ूरी देता है.
@Composable fun MoviesScreenLazy(movies: List<Movie>) { LazyColumn { items(movies, key = { movie -> movie.id }) { movie -> MovieOverview(movie) } } }
इनपुट में बदलाव न होने पर स्किप करना
बदलाव के दौरान, कंपोज़ेबल में मौजूद कुछ फ़ंक्शन में अगर उनके इनपुट पिछले निर्देश से नहीं बदले हैं, तो एक्ज़ीक्यूशन को पूरी तरह से स्किप कर दिया जाएगा कंपोज़िशन.
किसी कंपोज़ेबल फ़ंक्शन को स्किप किया जा सकता है, जब तक:
- इस फ़ंक्शन में एक गैर-
Unit
रिटर्न टाइप है - फ़ंक्शन को
@NonRestartableComposable
या@NonSkippableComposable
के साथ एनोटेट किया गया है - ज़रूरी पैरामीटर ऐसा है जो स्थिर नहीं है
स्ट्रॉन्ग स्किपिंग एक एक्सपेरिमेंटल कंपाइलर मोड है. इसमें आखिरी ज़रूरी शर्त को कम किया गया है.
किसी टाइप को स्थिर माना जा सके, इसके लिए उसे नीचे दिए गए समझौते का पालन करना होगा:
- दो इंस्टेंस के लिए
equals
का नतीजा हमेशा एक ही रहेगा समान दो इंस्टेंस. - अगर इस टाइप की कोई सार्वजनिक प्रॉपर्टी बदलती है, तो कॉम्पोज़िशन को इसकी सूचना दी जाएगी.
- सभी तरह की सार्वजनिक प्रॉपर्टी भी स्थिर हैं.
कुछ ज़रूरी सामान्य टाइप इस अनुबंध में आते हैं
कंपोज़ कंपाइलर को स्टेबल माना जाएगा, भले ही वे साफ़ तौर पर
@Stable
एनोटेशन का इस्तेमाल करके, इसे स्थिर के तौर पर मार्क किया गया है:
- सभी प्रिमिटिव वैल्यू टाइप:
Boolean
,Int
,Long
,Float
,Char
वगैरह. - स्ट्रिंग
- सभी फ़ंक्शन टाइप (lambdas)
ये सभी टाइप, स्थिर कॉन्ट्रैक्ट का पालन कर सकते हैं, क्योंकि इनमें बदलाव नहीं किया जा सकता. इम्यूटेबल टाइप कभी नहीं बदलते, इसलिए उन्हें बदलाव के कॉम्पोज़िशन की सूचना कभी नहीं देनी पड़ती. इसलिए, इस कानूनी समझौते का पालन करना बहुत आसान होता है.
ध्यान दें कि एक तरह का फ़ॉर्मैट स्थिर है, लेकिन इसमें बदलाव किया जा सकता है. वह टाइप, Compose का MutableState
है
टाइप करें. अगर कोई वैल्यू MutableState
में रखी जाती है, तो स्टेट ऑब्जेक्ट के बीच की कुल वैल्यू होगी
को स्थिर माना जाता है, क्योंकि Compose में कोई बदलाव होने पर उसे सूचना दी जाएगी
State
की .value
प्रॉपर्टी.
जब पैरामीटर के तौर पर किसी कॉम्पोज़ेबल में पास किए गए सभी टाइप स्थिर होते हैं, तो यूज़र इंटरफ़ेस (यूआई) ट्री में कॉम्पोज़ेबल की पोज़िशन के आधार पर, पैरामीटर वैल्यू की तुलना की जाती है. अगर सभी वैल्यू में कोई बदलाव नहीं हुआ है, तो फिर से क्रम में लगाने की सुविधा को स्किप कर दिया जाता है, क्योंकि पिछला कॉल.
Compose किसी टाइप को तब ही स्टेबल मानता है, जब वह उसे साबित कर सके. उदाहरण के लिए, इंटरफ़ेस को आम तौर पर स्टेबल नहीं माना जाता है और इसे बदला जा सकने वाला पब्लिक टाइप माना जाता है. ऐसी प्रॉपर्टी भी स्थिर नहीं हैं जिन्हें लागू नहीं किया जा सकता.
अगर Compose यह पता नहीं लगा पा रहा है कि कोई टाइप स्थिर है या नहीं, लेकिन आपको Compose को उसे स्थिर मानने के लिए मजबूर करना है, तो उसे @Stable
एनोटेशन के साथ मार्क करें.
// Marking the type as stable to favor skipping and smart recompositions. @Stable interface UiState<T : Result<T>> { val value: T? val exception: Throwable? val hasError: Boolean get() = exception != null }
ऊपर दिए गए कोड स्निपेट में, UiState
एक इंटरफ़ेस है. इसलिए, Compose आम तौर पर इस टाइप को अस्थिर मान सकता है. @Stable
एनोटेशन जोड़कर, Compose को बताया जाता है कि यह टाइप स्थिर है. इससे Compose, स्मार्ट रीकंपोज़िशन को प्राथमिकता दे पाता है. इसका यह भी मतलब है कि अगर इंटरफ़ेस का इस्तेमाल पैरामीटर टाइप के तौर पर किया जाता है, तो Compose अपने सभी लागू होने के तरीकों को स्थिर मानेगा.
फ़िलहाल कोई सुझाव नहीं है.
अपने Google खाते में साइन इन करने की कोशिश करें.