नेविगेशन की स्थिति सेव करना और मैनेज करना

इन सेक्शन में, बैक स्टैक को सेव करने और बैक स्टैक में मौजूद एंट्री से जुड़ी स्थिति को सेव करने की रणनीतियों के बारे में बताया गया है.

पिछली ऐक्टिविटी को सेव करना

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

rememberNavBackStack का इस्तेमाल करें

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

rememberNavBackStack के सही तरीके से काम करने के लिए, आपके बैक स्टैक में मौजूद हर कुंजी को कुछ ज़रूरी शर्तों का पालन करना होगा:

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

यहां दिए गए स्निपेट में, rememberNavBackStack को सही तरीके से लागू करने का तरीका बताया गया है:

@Serializable
data object Home : NavKey

@Composable
fun NavBackStack() {
    val backStack = rememberNavBackStack(Home)
}

अन्य विकल्प: ViewModel में सेव करना

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

  • पक्का करें कि आपकी कुंजियां क्रम से लगाई जा सकती हों: rememberNavBackStack की तरह ही, आपकी नेविगेशन कुंजियों को क्रम से लगाया जा सकता हो.
  • सीरियलाइज़ेशन और डीसीरियलाइज़ेशन को मैन्युअल तरीके से मैनेज करें: हर कुंजी के सीरियलाइज़ किए गए वर्शन को परसिस्टेंट स्टोरेज में मैन्युअल तरीके से सेव करने और उससे डीसीरियलाइज़ करने की ज़िम्मेदारी आपकी है. उदाहरण के लिए, SharedPreferences, डेटाबेस या फ़ाइल) को सेव करें. ऐसा तब करें, जब आपका ऐप्लिकेशन बैकग्राउंड में जा रहा हो या उसे वापस लाया जा रहा हो.

ViewModel सेकंड से NavEntry सेकंड तक के वीडियो को टारगेट करना

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

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

androidx.lifecycle:lifecycle-viewmodel-navigation3 ऐड-ऑन लाइब्रेरी, इस काम के लिए NavEntryDecorator उपलब्ध कराती है. यह डेकोरेटर, हर NavEntry के लिए ViewModelStoreOwner उपलब्ध कराता है. जब किसी NavEntry के कॉन्टेंट में ViewModel बनाया जाता है (जैसे, Compose में viewModel() का इस्तेमाल करके), तो यह बैक स्टैक में मौजूद उस NavEntry की कुंजी के हिसाब से अपने-आप स्कोप हो जाता है. इसका मतलब है कि NavEntry को बैक स्टैक में जोड़ने पर, ViewModel बनाया जाता है. साथ ही, इसे हटाने पर मिटा दिया जाता है.

NavEntry के लिए ViewModel को स्कोप करने के लिए, NavEntryDecorator का इस्तेमाल करने के लिए, यह तरीका अपनाएं:

  1. अपनी app/build.gradle.kts फ़ाइल में, androidx.lifecycle:lifecycle-viewmodel-navigation3 डिपेंडेंसी जोड़ें.
  2. NavDisplay बनाते समय, entryDecorators की सूची में rememberSaveableStateHolderNavEntryDecorator() जोड़ें.
  3. अपने NavDisplay में अन्य डेकोरेटर जोड़ें.

NavDisplay(
    entryDecorators = listOf(
        // Add the default decorators for managing scenes and saving state
        rememberSceneSetupNavEntryDecorator(),
        rememberSavedStateNavEntryDecorator(),
        // Then add the view model store decorator
        rememberViewModelStoreNavEntryDecorator()
    ),
    backStack = backStack,
    entryProvider = entryProvider { },
)