फ़्रैगमेंट के साथ सेव करने की स्थिति

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

यहां दी गई टेबल में उन कार्रवाइयों के बारे में बताया गया है जिनकी वजह से आपके फ़्रैगमेंट की स्थिति बदल जाती है. साथ ही, यह भी बताया गया है कि उन बदलावों के दौरान, अलग-अलग तरह की स्थिति बनी रहती है या नहीं. टेबल में बताई गई स्थिति के टाइप इस तरह के हैं:

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

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

कार्रवाई वैरिएबल स्थिति देखें SavedState NonConfig
पिछली गतिविधियों में जोड़ा गया x
कॉन्फ़िगरेशन में बदलाव x
प्रोसेस बंद होना/फिर से शुरू होना x ✓*
हटाया गया, पिछली गतिविधियों में नहीं जोड़ा गया x x x x
होस्ट का सेशन खत्म हो गया x x x x

* ViewModel के लिए सेव की गई स्थिति वाले मॉड्यूल का इस्तेमाल करके, प्रोसेस के बंद होने पर भी NonConfig स्थिति को बनाए रखा जा सकता है.

टेबल 1: फ़्रैगमेंट को नुकसान पहुंचाने वाले अलग-अलग ऑपरेशन और अलग-अलग तरह की स्थिति पर उनका असर.

आइए, एक उदाहरण देखते हैं. ऐसी स्क्रीन देखें जो एक रैंडम स्ट्रिंग जनरेट करती है, उसे TextView में दिखाती है, और किसी दोस्त को स्ट्रिंग भेजने से पहले उसमें बदलाव करने का विकल्प देती है:

रैंडम टेक्स्ट जनरेटर ऐप्लिकेशन, जो अलग-अलग तरह की स्थिति दिखाता है
पहला डायग्राम. रैंडम टेक्स्ट जनरेटर ऐप्लिकेशन, जो अलग-अलग तरह की स्थिति दिखाता है.

उदाहरण के लिए, मान लें कि जब उपयोगकर्ता 'बदलाव करें' बटन को दबाता है, तो ऐप्लिकेशन EditText व्यू दिखाता है, जहां उपयोगकर्ता मैसेज में बदलाव कर सकता है. अगर उपयोगकर्ता रद्द करें पर क्लिक करता है, तो EditText व्यू हट जाना चाहिए और उसकी दिखने की सेटिंग View.GONE पर सेट हो जानी चाहिए. बेहतरीन अनुभव देने के लिए, ऐसी स्क्रीन में डेटा के चार हिस्से मैनेज करने की ज़रूरत पड़ सकती है:

डेटा टाइप राज्य का टाइप ब्यौरा
seed Long NonConfig किसी भी क्रम में कोई नया काम करने के लिए इस्तेमाल किए गए बीज. ViewModel बनाए जाने पर जनरेट होता है.
randomGoodDeed String सेव किया गया स्टेटस + वैरिएबल पहली बार फ़्रैगमेंट बनाने पर जनरेट होती है. randomGoodDeed को सेव किया जाता है, ताकि यह पक्का किया जा सके कि पूरी तरह से मरने और मनोरंजन के बाद भी लोगों को एक जैसा कोई अच्छा काम दिखे.
isEditing Boolean SavedState + वैरिएबल जब उपयोगकर्ता बदलाव करना शुरू करता है, तो बूलियन फ़्लैग true पर सेट हो जाता है. isEditing को सेव किया जाता है, ताकि यह पक्का किया जा सके कि फ़्रैगमेंट को फिर से बनाने पर, स्क्रीन पर बदलाव किया जा रहा है.
बदला गया टेक्स्ट Editable स्टेटस देखें (EditText के मालिकाना हक वाला) EditText व्यू में, बदलाव किया गया टेक्स्ट. EditText व्यू इस टेक्स्ट को सेव करता है, ताकि यह पक्का किया जा सके कि उपयोगकर्ता के अधूरे बदलाव सेव रहेंगे.

दूसरी टेबल: इसमें बताया गया है कि रैंडम टेक्स्ट जनरेटर ऐप्लिकेशन को क्या मैनेज करना चाहिए.

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

स्थिति देखना

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

उदाहरण के लिए, पिछली स्थिति में, बदली गई स्ट्रिंग EditText में रखी गई है. EditText, दिखाए जा रहे टेक्स्ट की वैल्यू के साथ-साथ, चुने गए किसी टेक्स्ट का शुरू और अंत जैसी अन्य जानकारी भी जानता है.

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

<EditText
    android:id="@+id/good_deed_edit_text"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

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

SavedState

आपके फ़्रैगमेंट की ज़िम्मेदारी, डाइनैमिक स्टेटस की कम मात्रा को मैनेज करना है. यह स्टेटस, फ़्रैगमेंट के काम करने के तरीके के लिए ज़रूरी है. Fragment.onSaveInstanceState(Bundle) का इस्तेमाल करके, आसानी से सीरियलाइज़ किए गए डेटा को बनाए रखा जा सकता है. Activity.onSaveInstanceState(Bundle) की तरह ही, बंडल में डाला गया डेटा, कॉन्फ़िगरेशन में होने वाले बदलावों, प्रोसेस के बंद होने, और फिर से शुरू होने के दौरान भी सेव रहता है. यह डेटा, आपके फ़्रैगमेंट के onCreate(Bundle), onCreateView(LayoutInflater, ViewGroup, Bundle), और onViewCreated(View, Bundle) तरीकों में उपलब्ध होता है.

पिछले उदाहरण की तरह, randomGoodDeed वह डीड है जो उपयोगकर्ता को दिखाया जाता है. साथ ही, isEditing एक फ़्लैग है, जो यह तय करता है कि फ़्रैगमेंट EditText दिखाता है या छिपाता है. सेव किए गए इस स्टेटस को onSaveInstanceState(Bundle) का इस्तेमाल करके बनाए रखना चाहिए, जैसा कि इस उदाहरण में दिखाया गया है:

Kotlin

override fun onSaveInstanceState(outState: Bundle) {
    super.onSaveInstanceState(outState)
    outState.putBoolean(IS_EDITING_KEY, isEditing)
    outState.putString(RANDOM_GOOD_DEED_KEY, randomGoodDeed)
}

Java

@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putBoolean(IS_EDITING_KEY, isEditing);
    outState.putString(RANDOM_GOOD_DEED_KEY, randomGoodDeed);
}

onCreate(Bundle) में स्थिति को वापस लाने के लिए, बंडल से सेव की गई वैल्यू को वापस पाएं:

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    isEditing = savedInstanceState?.getBoolean(IS_EDITING_KEY, false)
    randomGoodDeed = savedInstanceState?.getString(RANDOM_GOOD_DEED_KEY)
            ?: viewModel.generateRandomGoodDeed()
}

Java

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (savedInstanceState != null) {
        isEditing = savedInstanceState.getBoolean(IS_EDITING_KEY, false);
        randomGoodDeed = savedInstanceState.getString(RANDOM_GOOD_DEED_KEY);
    } else {
        randomGoodDeed = viewModel.generateRandomGoodDeed();
    }
}

टेबल 1 में बताया गया है कि फ़्रैगमेंट को बैकस्टैक पर डालने पर, वैरिएबल बरकरार रहते हैं. उन्हें सेव की गई स्थिति के तौर पर इस्तेमाल करने से, यह पक्का होता है कि वे सभी डेटा मिटाने वाले ऑपरेशन के दौरान भी बने रहते हैं.

NonConfig

NonConfig डेटा को आपके फ़्रैगमेंट के बाहर रखा जाना चाहिए, जैसे कि ViewModel में. ऊपर दिए गए पिछले उदाहरण में, ViewModel में seed (हमारी नॉन कॉन्फ़िगरेशन स्थिति) जनरेट हुआ है. इसकी स्थिति को बनाए रखने का लॉजिक, ViewModel के पास होता है.

Kotlin

public class RandomGoodDeedViewModel : ViewModel() {
    private val seed = ... // Generate the seed

    private fun generateRandomGoodDeed(): String {
        val goodDeed = ... // Generate a random good deed using the seed
        return goodDeed
    }
}

Java

public class RandomGoodDeedViewModel extends ViewModel {
    private Long seed = ... // Generate the seed

    private String generateRandomGoodDeed() {
        String goodDeed = ... // Generate a random good deed using the seed
        return goodDeed;
    }
}

ViewModel क्लास, कॉन्फ़िगरेशन में होने वाले बदलावों के बावजूद डेटा को सुरक्षित रखती है. जैसे, स्क्रीन घुमाना. साथ ही, फ़्रैगमेंट को बैक स्टैक पर डालने पर, डेटा मेमोरी में बना रहता है. प्रोसेस के बंद होने और फिर से शुरू होने के बाद, ViewModel को फिर से बनाया जाता है और एक नया seed जनरेट होता है. ViewModel में SavedState मॉड्यूल जोड़ने से, ViewModel को प्रोसेस के बंद होने और फिर से शुरू होने के दौरान, आसान स्थिति बनाए रखने में मदद मिलती है.

अन्य संसाधन

फ़्रैगमेंट की स्थिति मैनेज करने के बारे में ज़्यादा जानने के लिए, यहां दिए गए अन्य संसाधन देखें.

कोडलैब

गाइड