यूज़र इंटरफ़ेस (यूआई) की स्थितियां सेव करें

इस गाइड में, यूज़र इंटरफ़ेस (यूआई) की स्थिति के बारे में उपयोगकर्ता की उम्मीदों के बारे में बताया गया है. साथ ही, स्थिति को बनाए रखने के लिए उपलब्ध विकल्पों के बारे में बताया गया है.

सिस्टम के होस्ट ऐक्टिविटी या ऐप्लिकेशन प्रोसेस को बंद करने के बाद, यूज़र इंटरफ़ेस (यूआई) की स्थिति को तुरंत सेव और वापस लाना ज़रूरी है. इससे उपयोगकर्ता को बेहतर अनुभव मिलता है. उपयोगकर्ता यह उम्मीद करते हैं कि यूज़र इंटरफ़ेस (यूआई) की स्थिति में कोई बदलाव नहीं होगा. हालांकि, सिस्टम स्क्रीन को होस्ट करने वाली गतिविधि और उसकी सेव की गई स्थिति को मिटा सकता है.

उपयोगकर्ता की उम्मीदों और सिस्टम के व्यवहार के बीच के अंतर को कम करने के लिए, इन तरीकों का इस्तेमाल करें:

  • ViewModel ऑब्जेक्ट.
  • इन कॉन्टेक्स्ट में सेव की गई स्थिति:
  • लोकल स्टोरेज. इसका इस्तेमाल, ऐप्लिकेशन और स्क्रीन ट्रांज़िशन के दौरान यूज़र इंटरफ़ेस (यूआई) की स्थिति को बनाए रखने के लिए किया जाता है.

सबसे सही समाधान, आपके यूज़र इंटरफ़ेस (यूआई) डेटा की जटिलता, आपके ऐप्लिकेशन के इस्तेमाल के उदाहरणों, और डेटा ऐक्सेस करने की स्पीड और मेमोरी के इस्तेमाल के बीच संतुलन बनाने पर निर्भर करता है.

पक्का करें कि आपका ऐप्लिकेशन, उपयोगकर्ताओं की उम्मीदों के मुताबिक हो. साथ ही, यह तेज़ और रिस्पॉन्सिव इंटरफ़ेस उपलब्ध कराता हो. यूज़र इंटरफ़ेस (यूआई) में डेटा लोड करने में देरी न हो. खास तौर पर, रोटेशन जैसे सामान्य कॉन्फ़िगरेशन में बदलाव के बाद.

उपयोगकर्ता की उम्मीदें और सिस्टम का व्यवहार

उपयोगकर्ता की कार्रवाई के आधार पर, उन्हें उम्मीद होती है कि यूज़र इंटरफ़ेस (यूआई) की स्थिति या तो मिटा दी जाएगी या उसे बनाए रखा जाएगा. कुछ मामलों में, सिस्टम अपने-आप वह काम करता है जो उपयोगकर्ता चाहता है. अन्य मामलों में, सिस्टम इसका उल्टा करता है.

उपयोगकर्ता के अनुरोध पर यूज़र इंटरफ़ेस (यूआई) की स्थिति को खारिज करना

उपयोगकर्ता यह उम्मीद करता है कि जब वह किसी स्क्रीन पर नेविगेट करता है, तो उसकी ट्रांज़िएंट यूज़र इंटरफ़ेस (यूआई) स्थिति तब तक एक जैसी बनी रहे, जब तक वह उसे पूरी तरह से खारिज नहीं कर देता. उपयोगकर्ता, स्क्रीन या ऐप्लिकेशन को पूरी तरह से खारिज कर सकता है. इसके लिए, उसे यह तरीका अपनाना होगा:

  • खास जानकारी (हाल ही के ऐप्लिकेशन) स्क्रीन से ऐप्लिकेशन को स्वाइप करके हटाना.
  • सेटिंग स्क्रीन से ऐप्लिकेशन को बंद करना या उसे ज़बरदस्ती बंद करना.
  • डिवाइस को रीबूट किया जा रहा है.
  • "फ़िनिशिंग" से जुड़ी कोई कार्रवाई पूरी करना. यह कार्रवाई Activity.finish() की मदद से की जाती है.

विज्ञापन को पूरी तरह से खारिज करने के इन मामलों में, उपयोगकर्ता यह मान लेता है कि वह स्क्रीन से हमेशा के लिए हट गया है. अगर वह वापस आता है, तो उसे उम्मीद होती है कि स्क्रीन नए सिरे से शुरू होगी. सूचना खारिज करने के इन सभी मामलों में, सिस्टम का व्यवहार उपयोगकर्ता की उम्मीदों के मुताबिक होता है. होस्ट गतिविधि का इंस्टेंस डिस्ट्रॉय हो जाएगा और मेमोरी से हटा दिया जाएगा. साथ ही, इसमें सेव किया गया कोई भी स्टेट और इससे जुड़ा कोई भी सेव किया गया स्टेट रिकॉर्ड भी हटा दिया जाएगा.

पूरी तरह से खारिज करने के इस नियम के कुछ अपवाद हैं. उदाहरण के लिए, कोई उपयोगकर्ता यह उम्मीद कर सकता है कि ब्राउज़र उसे उसी वेबपेज पर ले जाए जिसे वह ब्राउज़र बंद करने से पहले देख रहा था. इसके लिए, वह 'वापस जाएं' बटन का इस्तेमाल करता है.

सिस्टम की ओर से यूज़र इंटरफ़ेस (यूआई) की स्थिति को खारिज करना

कोई उपयोगकर्ता यह उम्मीद करता है कि स्क्रीन के यूज़र इंटरफ़ेस (यूआई) की स्थिति, कॉन्फ़िगरेशन में होने वाले बदलाव के दौरान भी एक जैसी बनी रहे. जैसे, स्क्रीन को घुमाना या मल्टी-विंडो मोड में स्विच करना. हालांकि, कॉन्फ़िगरेशन में इस तरह का बदलाव होने पर, सिस्टम डिफ़ॉल्ट रूप से होस्ट गतिविधि को मिटा देता है. इससे, उसमें सेव किया गया कोई भी यूज़र इंटरफ़ेस (यूआई) स्टेट मिट जाती है. डिवाइस कॉन्फ़िगरेशन के बारे में ज़्यादा जानने के लिए, Jetpack Compose में कॉन्फ़िगरेशन में हुए बदलावों पर प्रतिक्रिया देना लेख पढ़ें.

ध्यान दें कि कॉन्फ़िगरेशन में बदलाव करने के लिए, डिफ़ॉल्ट व्यवहार को बदला जा सकता है. हालांकि, ऐसा करने का सुझाव नहीं दिया जाता. ज़्यादा जानकारी के लिए, कॉन्फ़िगरेशन में हुए बदलाव को मैनेज करना लेख पढ़ें.

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

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

यूज़र इंटरफ़ेस (यूआई) की स्थिति को बनाए रखने के विकल्प

जब यूज़र इंटरफ़ेस (यूआई) की स्थिति के बारे में उपयोगकर्ता की उम्मीदें, सिस्टम के डिफ़ॉल्ट व्यवहार से मेल नहीं खाती हैं, तो आपको उपयोगकर्ता के यूज़र इंटरफ़ेस (यूआई) की स्थिति को सेव और रीस्टोर करना होगा. इससे यह पक्का किया जा सकेगा कि सिस्टम की वजह से होने वाला डिस्ट्रक्शन, उपयोगकर्ता को साफ़ तौर पर दिखे.

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

ViewModel सेव की गई स्थिति स्थायी जगह
सेव करने की जगह मेमोरी में मेमोरी में डिस्क या नेटवर्क पर
कॉन्फ़िगरेशन में बदलाव होने पर भी बना रहता है हां हां हां
सिस्टम की वजह से प्रोसेस बंद होने पर भी बना रहता है नहीं हां हां
उपयोगकर्ता के स्क्रीन बंद करने/finish() पर भी मौजूद रहता है नहीं नहीं हां
डेटा से जुड़ी सीमाएं जटिल ऑब्जेक्ट ठीक हैं, लेकिन उपलब्ध मेमोरी के हिसाब से स्पेस सीमित है सिर्फ़ प्रिमिटिव टाइप और आसान, छोटे ऑब्जेक्ट के लिए, जैसे कि String यह सिर्फ़ डिस्क स्पेस या नेटवर्क संसाधन से डेटा वापस पाने की लागत / समय के हिसाब से सीमित होता है
पढ़ने/लिखने का समय क्विक (सिर्फ़ मेमोरी ऐक्सेस करने के लिए) धीमा (सीरियलाइज़ेशन/डीसीरियलाइज़ेशन की ज़रूरत होती है) धीमा (इसके लिए डिस्क ऐक्सेस या नेटवर्क लेन-देन की ज़रूरत होती है)

कॉन्फ़िगरेशन में होने वाले बदलावों को हैंडल करने के लिए ViewModel का इस्तेमाल करना

ViewModel, यूज़र इंटरफ़ेस (यूआई) से जुड़े डेटा को सेव करने और मैनेज करने के लिए सबसे सही है. ऐसा तब होता है, जब उपयोगकर्ता ऐप्लिकेशन का इस्तेमाल कर रहा हो. इससे यूज़र इंटरफ़ेस (यूआई) के डेटा को तुरंत ऐक्सेस किया जा सकता है. साथ ही, यह रोटेशन, विंडो का साइज़ बदलने, और कॉन्फ़िगरेशन में होने वाले अन्य सामान्य बदलावों के दौरान, नेटवर्क या डिस्क से डेटा को फिर से फ़ेच करने से बचाता है. ViewModel को लागू करने का तरीका जानने के लिए, ViewModel गाइड देखें.

ViewModel, डेटा को मेमोरी में सेव करता है. इसका मतलब है कि डिस्क या नेटवर्क से डेटा को वापस पाने की तुलना में, इसे वापस पाना सस्ता होता है. ViewModel, लाइफ़साइकल के मालिक से जुड़ा होता है. जैसे, नेविगेशन डेस्टिनेशन या कोई ऐक्टिविटी. यह कॉन्फ़िगरेशन में बदलाव के दौरान मेमोरी में बना रहता है. साथ ही, सिस्टम, ViewModel को लाइफ़साइकल के नए मालिक के इंस्टेंस के साथ अपने-आप जोड़ देता है. यह इंस्टेंस, कॉन्फ़िगरेशन में बदलाव की वजह से बनता है.

सेव की गई स्थिति के उलट, सिस्टम की ओर से शुरू की गई प्रोसेस के बंद होने पर ViewModels डिस्ट्रॉय हो जाते हैं. अगर सिस्टम की वजह से ViewModel बंद हो जाता है, तो डेटा को फिर से लोड करने के लिए, SavedStateHandle API का इस्तेमाल करें. इसके अलावा, अगर डेटा यूज़र इंटरफ़ेस (यूआई) से जुड़ा है और उसे ViewModel में सेव करने की ज़रूरत नहीं है, तो rememberSerializable का इस्तेमाल करें. प्रिमिटिव डेटा टाइप या ऐसे मामलों के लिए जहां आपको @Serializable का इस्तेमाल नहीं करना है, rememberSaveable का इस्तेमाल करें. अगर डेटा ऐप्लिकेशन डेटा है, तो उसे डिस्क में सेव करना बेहतर हो सकता है.

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

सिस्टम की वजह से प्रोसेस बंद होने की समस्या को ठीक करने के लिए, सेव की गई स्थिति को बैकअप के तौर पर इस्तेमाल करना

Compose में rememberSerializable और rememberSaveable जैसे एपीआई और ViewModels में SavedStateHandle, यूज़र इंटरफ़ेस (यूआई) की स्थिति को फिर से लोड करने के लिए ज़रूरी डेटा सेव करते हैं. ऐसा तब होता है, जब सिस्टम किसी कॉम्पोनेंट को बंद कर देता है और बाद में उसे फिर से बनाता है. जटिल डेटा स्ट्रक्चर को ज़्यादा असरदार तरीके से हैंडल करने के लिए, SavedStateHandle saved {} एक्सटेंशन के ज़रिए Kotlinx Serialization का इस्तेमाल करता है. इससे, स्टैंडर्ड प्रिमिटिव टाइप के साथ-साथ टाइप-सेफ़ ऑब्जेक्ट को आसानी से सेव और वापस लाया जा सकता है. rememberSaveable का इस्तेमाल करके, सेव की गई स्टेट को लागू करने का तरीका जानने के लिए, स्टेट और Jetpack Compose लेख पढ़ें.

सेव किए गए स्टेट बंडल, कॉन्फ़िगरेशन में होने वाले बदलावों और प्रोसेस के बंद होने के दौरान बने रहते हैं. हालांकि, स्टोरेज और स्पीड के हिसाब से इनकी सीमाएं होती हैं, क्योंकि अलग-अलग एपीआई डेटा को क्रम से लगाते हैं. अगर सीरियल किए जा रहे ऑब्जेक्ट जटिल हैं, तो सीरियलाइज़ेशन में बहुत ज़्यादा मेमोरी खर्च हो सकती है. कॉन्फ़िगरेशन में बदलाव के दौरान, यह प्रोसेस मुख्य थ्रेड पर होती है. इसलिए, लंबे समय तक चलने वाले सीरियलाइज़ेशन की वजह से फ़्रेम ड्रॉप हो सकते हैं और विज़ुअल स्टटर हो सकता है.

सेव की गई स्थिति का इस्तेमाल, बड़ी मात्रा में डेटा सेव करने के लिए न करें. जैसे, बिटमैप. साथ ही, ऐसे जटिल डेटा स्ट्रक्चर के लिए भी इसका इस्तेमाल न करें जिन्हें सीरियलाइज़ या डीसीरियलाइज़ करने में ज़्यादा समय लगता है. इसके बजाय, सिर्फ़ प्रिमिटिव टाइप और आसान, छोटे ऑब्जेक्ट सेव करें. जैसे, String. इसलिए, सेव की गई स्थिति का इस्तेमाल करके, ज़रूरी डेटा को कम से कम मात्रा में सेव करें. जैसे, आईडी. इससे, अगर डेटा को सेव करने के अन्य तरीके काम नहीं करते हैं, तो यूज़र इंटरफ़ेस (यूआई) को उसकी पिछली स्थिति में वापस लाने के लिए ज़रूरी डेटा को फिर से बनाया जा सकेगा. ज़्यादातर ऐप्लिकेशन को इसे लागू करना चाहिए, ताकि सिस्टम की ओर से प्रोसेस बंद होने की समस्या को ठीक किया जा सके.

आपके ऐप्लिकेशन के इस्तेमाल के उदाहरणों के आधार पर, हो सकता है कि आपको सेव किए गए स्टेट का इस्तेमाल करने की ज़रूरत न पड़े. उदाहरण के लिए, कोई ब्राउज़र उपयोगकर्ता को ठीक उसी वेबपेज पर वापस ले जा सकता है जिसे वह ब्राउज़र बंद करने से पहले देख रहा था. अगर आपकी गतिविधि इस तरह से काम करती है, तो सेव किए गए स्टेट का इस्तेमाल न करें. इसके बजाय, सभी डेटा को स्थानीय तौर पर सेव करें.

इसके अलावा, किसी इंटेंट से कोई गतिविधि खोलने पर, एक्स्ट्रा का बंडल गतिविधि को तब भी डिलीवर किया जाता है, जब कॉन्फ़िगरेशन में बदलाव होता है और जब सिस्टम गतिविधि को वापस लाता है. अगर यूज़र इंटरफ़ेस (यूआई) की स्थिति से जुड़े किसी डेटा को इंटेंट एक्स्ट्रा के तौर पर पास किया गया था, तो गतिविधि लॉन्च होने पर, सेव किए गए स्टेट बंडल के बजाय एक्स्ट्रा बंडल का इस्तेमाल किया जा सकता है. जैसे, खोज क्वेरी. इंटेंट एक्स्ट्रा के बारे में ज़्यादा जानने के लिए, इंटेंट और इंटेंट फ़िल्टर देखें.

इन दोनों ही स्थितियों में, आपको ViewModel का इस्तेमाल करना चाहिए, ताकि कॉन्फ़िगरेशन में बदलाव के दौरान डेटाबेस से डेटा को फिर से लोड करने में समय बर्बाद न हो.

अगर यूज़र इंटरफ़ेस (यूआई) का डेटा आसान और कम जगह घेरने वाला है, तो सेव की गई स्थिति के एपीआई का इस्तेमाल करके, स्थिति का डेटा सेव किया जा सकता है.

SavedStateRegistry का इस्तेमाल करके, सेव की गई स्थिति में हुक करना

Fragment 1.1.0 या इसकी ट्रांज़िटिव डिपेंडेंसी Activity 1.0.0 से शुरू होने वाले यूज़र इंटरफ़ेस (यूआई) कॉम्पोनेंट, जैसे कि ComponentActivity, SavedStateRegistryOwner को लागू करते हैं और SavedStateRegistry उपलब्ध कराते हैं, जो उस कॉम्पोनेंट से जुड़ा होता है. SavedStateRegistry की मदद से कॉम्पोनेंट, सेव की गई आपकी स्थिति में हुक कर सकते हैं, ताकि वे उसका इस्तेमाल कर सकें या उसमें योगदान दे सकें. उदाहरण के लिए, ViewModel के लिए Saved State मॉड्यूल, SavedStateRegistry का इस्तेमाल करके SavedStateHandle बनाता है और इसे आपके ViewModel ऑब्जेक्ट को उपलब्ध कराता है. savedStateRegistry को कॉल करके, लाइफ़साइकल के मालिक से SavedStateRegistry को वापस पाया जा सकता है.

सेव की गई स्थिति में योगदान देने वाले कॉम्पोनेंट को SavedStateRegistry.SavedStateProvider लागू करना होगा. यह एक ऐसा तरीका तय करता है जिसे saveState() कहा जाता है. saveState() तरीके से, आपका कॉम्पोनेंट एक Bundle दिखाता है. इसमें वह स्थिति शामिल होती है जिसे उस कॉम्पोनेंट से सेव किया जाना चाहिए. SavedStateRegistry, लाइफ़साइकल के मालिक के लाइफ़साइकल के सेविंग स्टेट फ़ेज़ के दौरान इस तरीके को कॉल करता है.

  class SearchManager : SavedStateRegistry.SavedStateProvider {
      companion object {
          private const val QUERY = "query"
      }

      private val query: String? = null

      ...

      override fun saveState(): Bundle {
          return bundleOf(QUERY to query)
      }
  }

SavedStateProvider रजिस्टर करने के लिए, registerSavedStateProvider() पर कॉल करें. साथ ही, सेवा देने वाली कंपनी के डेटा और सेवा देने वाली कंपनी से जोड़ने के लिए एक कुंजी पास करें.SavedStateRegistry सेवा देने वाली कंपनी के लिए पहले से सेव किए गए डेटा को, सेव की गई स्थिति से वापस पाया जा सकता है. इसके लिए, SavedStateRegistry पर consumeRestoredStateForKey() को कॉल करें. साथ ही, सेवा देने वाली कंपनी के डेटा से जुड़ी कुंजी पास करें.

ComponentActivity में, super.onCreate() को कॉल करने के बाद, onCreate() में SavedStateProvider रजिस्टर किया जा सकता है. इसके अलावा, SavedStateRegistryOwner पर LifecycleObserver सेट किया जा सकता है. इससे LifecycleOwner लागू होता है. साथ ही, ON_CREATE इवेंट होने पर SavedStateProvider को रजिस्टर किया जा सकता है. LifecycleObserver का इस्तेमाल करके, पहले से सेव की गई स्थिति को रजिस्टर करने और वापस पाने की प्रोसेस को SavedStateRegistryOwner से अलग किया जा सकता है.

  class SearchManager(registryOwner: SavedStateRegistryOwner) : SavedStateRegistry.SavedStateProvider {
      companion object {
          private const val PROVIDER = "search_manager"
          private const val QUERY = "query"
      }

      private val query: String? = null

      init {
          // Register a LifecycleObserver for when the Lifecycle hits ON_CREATE
          registryOwner.lifecycle.addObserver(LifecycleEventObserver { _, event ->
              if (event == Lifecycle.Event.ON_CREATE) {
                  val registry = registryOwner.savedStateRegistry

                  // Register this object for future calls to saveState()
                  registry.registerSavedStateProvider(PROVIDER, this)

                  // Get the previously saved state and restore it
                  val state = registry.consumeRestoredStateForKey(PROVIDER)

                  // Apply the previously saved state
                  query = state?.getString(QUERY)
              }
          }
      }

      override fun saveState(): Bundle {
          return bundleOf(QUERY to query)
      }

      ...
  }

  class SearchActivity : ComponentActivity() {
    private var searchManager = SearchManager(this)

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // Set up your Compose UI here
        setContent {
            // ...
        }
    }
  }

जटिल या बड़े डेटा के लिए, प्रोसेस बंद होने की समस्या को ठीक करने के लिए लोकल परसिस्टेंस का इस्तेमाल करना

स्थानीय स्टोरेज, जैसे कि डेटाबेस या DataStore, तब तक मौजूद रहेगा, जब तक आपका ऐप्लिकेशन उपयोगकर्ता के डिवाइस पर इंस्टॉल रहेगा. हालांकि, अगर उपयोगकर्ता आपके ऐप्लिकेशन का डेटा मिटा देता है, तो यह स्टोरेज मौजूद नहीं रहेगा. सिस्टम की ओर से शुरू की गई ऐप्लिकेशन प्रोसेस के बंद होने के बाद भी, इस तरह की लोकल मेमोरी में सेव किया गया डेटा मौजूद रहता है. हालांकि, इसे वापस पाने में ज़्यादा समय लग सकता है, क्योंकि इसे लोकल मेमोरी से मेमोरी में पढ़ना होगा. अक्सर, यह परसिस्टेंट लोकल स्टोरेज पहले से ही आपके ऐप्लिकेशन के आर्किटेक्चर का हिस्सा हो सकता है. इसका इस्तेमाल, उस डेटा को सेव करने के लिए किया जाता है जिसे आपको ऐप्लिकेशन खोलने और बंद करने पर भी नहीं मिटाना है.

ViewModel और rememberSerializable, rememberSaveable या SavedStateHandle का इस्तेमाल करके सेव किया गया स्टेट, लंबे समय तक डेटा सेव करने के समाधान नहीं हैं. इसलिए, ये डेटाबेस जैसे लोकल स्टोरेज के विकल्प नहीं हैं. इसके बजाय, आपको इन तरीकों का इस्तेमाल सिर्फ़ यूज़र इंटरफ़ेस (यूआई) की मौजूदा स्थिति को कुछ समय के लिए सेव करने के लिए करना चाहिए. साथ ही, ऐप्लिकेशन के अन्य डेटा के लिए हमेशा मौजूद रहने वाले स्टोरेज का इस्तेमाल करना चाहिए. अपने ऐप्लिकेशन के मॉडल डेटा को लंबे समय तक सेव रखने के लिए, लोकल स्टोरेज का इस्तेमाल कैसे करें, इस बारे में ज़्यादा जानने के लिए ऐप्लिकेशन के आर्किटेक्चर की गाइड देखें. उदाहरण के लिए, डिवाइस को रीस्टार्ट करने पर भी डेटा सेव रहता है.

यूज़र इंटरफ़ेस की स्थिति को मैनेज करना: बांटो और जीतो

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

  • लोकल परसिस्टेंस: यह कुकी, ऐप्लिकेशन का वह सारा डेटा सेव करती है जिसे आपको ऐप्लिकेशन खोलने और बंद करने पर भी सेव रखना है.
    • उदाहरण: गानों के ऑब्जेक्ट का कलेक्शन. इसमें ऑडियो फ़ाइलें और मेटाडेटा शामिल हो सकता है.
  • ViewModel: यह कुकी, यूज़र इंटरफ़ेस (यूआई) दिखाने के लिए ज़रूरी सभी डेटा को मेमोरी में सेव करती है. इसे स्क्रीन यूज़र इंटरफ़ेस (यूआई) की स्थिति कहा जाता है.
    • उदाहरण: हाल ही की खोज के गाने के ऑब्जेक्ट और हाल ही की खोज क्वेरी.
  • सेव की गई स्थिति (rememberSerializable, rememberSaveable, और SavedStateHandle): यह कुकी, कम मात्रा में डेटा सेव करती है. इस डेटा का इस्तेमाल, सिस्टम के बंद होने और फिर यूज़र इंटरफ़ेस (यूआई) को फिर से बनाने पर, यूज़र इंटरफ़ेस (यूआई) की स्थिति को फिर से लोड करने के लिए किया जाता है. यहां जटिल ऑब्जेक्ट सेव करने के बजाय, उन्हें डिवाइस के स्टोरेज में सेव करें. साथ ही, सेव की गई स्थिति वाले एपीआई में इन ऑब्जेक्ट के लिए यूनीक आईडी सेव करें.
    • उदाहरण: हाल ही में की गई सर्च क्वेरी को सेव करना.

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

जब उपयोगकर्ता कोई गाना जोड़ता है, तो ViewModel तुरंत इस डेटा को स्थानीय तौर पर सेव करने का काम सौंप देता है. अगर इस नए गाने को यूज़र इंटरफ़ेस (यूआई) में दिखाना है, तो आपको ViewModel ऑब्जेक्ट में मौजूद डेटा को भी अपडेट करना होगा, ताकि गाने को जोड़ा जा सके. ध्यान रखें कि डेटाबेस में सभी इंसर्ट, मुख्य थ्रेड से बाहर किए जाएं.

जब उपयोगकर्ता किसी गाने को खोजता है, तो डेटाबेस से लोड किए गए गाने के जटिल डेटा को स्क्रीन यूज़र इंटरफ़ेस (यूआई) की स्थिति के हिस्से के तौर पर, ViewModel ऑब्जेक्ट में तुरंत सेव किया जाना चाहिए.

जब ऐप्लिकेशन बैकग्राउंड में चला जाता है और सिस्टम उसकी स्थिति को सेव करता है, तो खोज क्वेरी को सेव की गई स्थिति वाले एपीआई का इस्तेमाल करके सेव किया जाना चाहिए. ऐसा तब किया जाता है, जब प्रोसेस फिर से शुरू होती है. इस ऐप्लिकेशन में सेव किए गए डेटा को लोड करने के लिए, यह जानकारी ज़रूरी है. इसलिए, खोज क्वेरी को ViewModel SavedStateHandle में सेव करें या अपने कंपोज़ेबल में rememberSerializable या rememberSaveable का इस्तेमाल करें. डेटा लोड करने और यूज़र इंटरफ़ेस (यूआई) को उसकी मौजूदा स्थिति में वापस लाने के लिए, आपको इस जानकारी की ज़रूरत होगी.

जटिल स्थितियों को पहले जैसा करना: टुकड़ों को फिर से जोड़ना

जब उपयोगकर्ता को ऐप्लिकेशन पर वापस आना होता है, तो यूज़र इंटरफ़ेस (यूआई) को फिर से बनाने के लिए, दो संभावित स्थितियां होती हैं:

  • सिस्टम, ऐप्लिकेशन प्रोसेस को बंद कर देता है. इसके बाद, यूज़र इंटरफ़ेस (यूआई) फिर से बनाया जाता है. सिस्टम के पास, सेव की गई स्थिति वाले एपीआई का इस्तेमाल करके सेव की गई क्वेरी है. ViewModel (SavedStateHandle का इस्तेमाल करके) या कंपोज़ेबल (rememberSerializable या rememberSaveable का इस्तेमाल करके) क्वेरी को अपने-आप रीस्टोर कर देता है. अगर कंपोज़ेबल, क्वेरी को वापस लाता है, तो यह क्वेरी को ViewModel को पास करता है. ViewModel देखता है कि खोज के नतीजे कैश मेमोरी में सेव नहीं हैं. इसके बाद, वह दी गई खोज क्वेरी का इस्तेमाल करके, खोज के नतीजे लोड करने का काम किसी दूसरे सिस्टम को सौंप देता है.
  • कॉन्फ़िगरेशन में बदलाव होने के बाद, यूज़र इंटरफ़ेस (यूआई) फिर से बनाया जाता है. ViewModel इंस्टेंस को डिस्ट्रॉय नहीं किया गया है. इसलिए, ViewModel के पास मेमोरी में कैश की गई पूरी जानकारी है. इसलिए, इसे डेटाबेस से फिर से क्वेरी करने की ज़रूरत नहीं है.

अन्य संसाधन

यूज़र इंटरफ़ेस (यूआई) की स्थितियों को सेव करने के बारे में ज़्यादा जानने के लिए, यहां दिए गए संसाधन देखें.

कोडलैब

कॉन्टेंट देखता है