कंपोज़ेबल का लाइफ़साइकल

इस पेज पर, आपको किसी कंपोज़ेबल के लाइफ़साइकल और 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 कंपोज़ेबल को हमेशा कॉल किया जाएगा. हर कॉल के लिए, एक यूनीक कॉल साइट और सोर्स पोज़िशन चुनी गई है, जिसका इस्तेमाल कंपाइलर पहचानने में आसानी होती है.

डायग्राम में दिखाया गया है कि ShowError फ़्लैग के &#39;सही&#39; में बदलने पर, पिछले कोड को कैसे फिर से लिखा जाता है. लॉगिन गड़बड़ी कंपोज़ेबल जोड़ दी गई है, लेकिन अन्य कंपोज़ेबल को फिर से नहीं बनाया गया है.

तीसरी इमेज. राज्य के कंपोज़िशन में 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)
            }
        }
    }
}

ऊपर दी गई जानकारी के साथ, भले ही सूची में मौजूद एलिमेंट बदल जाएं, लेकिन कंपोज़ की मदद से MovieOverview को किए जाने वाले कॉल और उनका फिर से इस्तेमाल कर सकते हैं.

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

छठी इमेज. नए कंपोज़िशन में MoviesScreen को दिखाना एलिमेंट को सूची में जोड़ा जाता है. ऐसा इसलिए है, क्योंकि MovieOverview कंपोज़ेबल बटन का इस्तेमाल करके, कंपोज़ की सुविधा पता लगाती है कि किन 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 किसी टाइप को स्टेबल तब ही मानता है, जब वह उसे साबित कर सके. उदाहरण के लिए, इंटरफ़ेस को आम तौर पर स्टेबल नहीं माना जाता है और इसे बदला जा सकने वाला पब्लिक टाइप माना जाता है. ऐसी प्रॉपर्टी भी स्थिर नहीं हैं जिन्हें लागू नहीं किया जा सकता.

अगर आपको यह पता नहीं चल पा रहा है कि कोई टाइप स्टेबल है, लेकिन आपको इसे स्टेबल के तौर पर लिखने के लिए, इसे @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 में लागू करने की प्रक्रिया स्थायी हो जाती है. ऐसा तब होता है, जब इंटरफ़ेस का इस्तेमाल पैरामीटर टाइप के तौर पर किया जाता है.