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

कॉन्सेप्ट और Jetpack Compose को लागू करने का तरीका

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

ViewModel

सेव की गई इंस्टेंस की स्थिति

स्थायी जगह

सेव करने की जगह

मेमोरी में

मेमोरी में

डिस्क या नेटवर्क पर

कॉन्फ़िगरेशन में बदलाव के बाद भी डेटा बना रहता है

हां

हां

हां

सिस्टम के अनुरोध पर, प्रोसेस के खत्म होने के बाद भी डेटा बना रहता है

नहीं

हां

हां

ऐक्टिविटी को पूरी तरह से खारिज करने/finish() के बाद भी डेटा बना रहता है

नहीं

नहीं

हां

डेटा से जुड़ी सीमाएं

कॉम्प्लेक्स ऑब्जेक्ट सेव किए जा सकते हैं. हालांकि, उपलब्ध मेमोरी के हिसाब से जगह सीमित होती है

सिर्फ़ प्रिमिटिव टाइप और आसान, छोटे ऑब्जेक्ट के लिए. जैसे, String

सिर्फ़ डिस्क स्पेस या नेटवर्क रिसॉर्स से डेटा वापस पाने की लागत / समय के हिसाब से सीमाएं लागू होती हैं

पढ़ने/लिखने में लगने वाला समय

तेज़ (सिर्फ़ मेमोरी ऐक्सेस)

धीमा (सीरियलाइज़ेशन/डीसीरियलाइज़ेशन की ज़रूरत होती है)

धीमा (डिस्क ऐक्सेस या नेटवर्क ट्रांज़ैक्शन की ज़रूरत होती है)

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

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

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

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

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

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

सिस्टम के अनुरोध पर, प्रोसेस के खत्म होने की स्थिति को हैंडल करने के लिए, सेव की गई इंस्टेंस की स्थिति को बैकअप के तौर पर इस्तेमाल करना

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

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

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

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

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

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

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

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

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

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

class SearchManager implements SavedStateRegistry.SavedStateProvider {
    private static String QUERY = "query";
    private String query = null;
    ...

    @NonNull
    @Override
    public Bundle saveState() {
        Bundle bundle = new Bundle();
        bundle.putString(QUERY, query);
        return bundle;
    }
}

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

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

Kotlin

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 SearchFragment : Fragment() {
    private var searchManager = SearchManager(this)
    ...
}

Java

class SearchManager implements SavedStateRegistry.SavedStateProvider {
    private static String PROVIDER = "search_manager";
    private static String QUERY = "query";
    private String query = null;

    public SearchManager(SavedStateRegistryOwner registryOwner) {
        registryOwner.getLifecycle().addObserver((LifecycleEventObserver) (source, event) -> {
            if (event == Lifecycle.Event.ON_CREATE) {
                SavedStateRegistry registry = registryOwner.getSavedStateRegistry();

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

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

                // Apply the previously saved state
                if (state != null) {
                    query = state.getString(QUERY);
                }
            }
        });
    }

    @NonNull
    @Override
    public Bundle saveState() {
        Bundle bundle = new Bundle();
        bundle.putString(QUERY, query);
        return bundle;
    }

    ...
}

class SearchFragment extends Fragment {
    private SearchManager searchManager = new SearchManager(this);
    ...
}

कॉम्प्लेक्स या बड़े डेटा के लिए, प्रोसेस के खत्म होने की स्थिति को हैंडल करने के लिए, लोकल परसिस्टेंस का इस्तेमाल करना

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

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

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

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

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

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

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

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

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

कॉम्प्लेक्स स्थितियों को वापस लाना: हिस्सों को फिर से जोड़ना

जब कोई व्यक्ति ऐक्टिविटी पर वापस आता है, तो ऐक्टिविटी को फिर से बनाने के लिए दो स्थितियां हो सकती हैं:

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

अन्य संसाधन

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

ब्लॉग

कोडलैब