ViewModel के लिए सेव किया गया स्टेट मॉड्यूल Android Jetpack का हिस्सा है.
जैसा कि इसमें बताया गया है
यूज़र इंटरफ़ेस (यूआई) की स्थितियों को सेव करना,
ViewModel
ऑब्जेक्ट हैंडल कर सकते हैं
कॉन्फ़िगरेशन बदल जाता है, इसलिए आपको रोटेशन की स्थिति की चिंता करने की आवश्यकता नहीं है
या अन्य मामलों में. हालांकि, अगर आपको सिस्टम से शुरू की गई प्रोसेस को मैनेज करना हो, तो
मौत हो, तो हो सकता है कि आप बैकअप के रूप में SavedStateHandle
API का इस्तेमाल करना चाहें.
यूज़र इंटरफ़ेस (यूआई) की स्थिति को आम तौर पर ViewModel
ऑब्जेक्ट में सेव या रेफ़र किया जाता है, न कि
गतिविधियों की वजह से, onSaveInstanceState()
या rememberSaveable
का इस्तेमाल करने के लिए
बॉयलरप्लेट जो सहेजा गया स्टेट मॉड्यूल
आपके लिए संभाल सकता है.
इस मॉड्यूल का इस्तेमाल करने पर, ViewModel
ऑब्जेक्ट को
SavedStateHandle
ऑब्जेक्ट
इसके कंस्ट्रक्टर की मदद से ऐसा करता है. यह ऑब्जेक्ट एक की-वैल्यू मैप है. इससे आपको
सेव की गई स्थिति में ऑब्जेक्ट लिखने और उसे वापस लाने के लिए. ये वैल्यू
सिस्टम से प्रोसेस खत्म हो जाने के बाद भी बना रहता है
एक ही ऑब्जेक्ट से होकर गुज़रता है.
सेव की गई स्थिति, आपके टास्क स्टैक से जुड़ी है. अगर आपका टास्क स्टैक हट जाता है, तो राज्य से बाहर हो जाता है. ऐसा तब हो सकता है, जब किसी ऐप्लिकेशन को ज़बरदस्ती रोका जाता है और हाल ही के मेन्यू से ऐप्लिकेशन खोलें या डिवाइस को फिर से चालू करें. ऐसे मामलों में, टास्क स्टैक हट जाता है और सेव की गई स्थिति में जानकारी को वापस नहीं लाया जा सकता. तय सीमा में उपयोगकर्ता की ओर से शुरू की गई यूज़र इंटरफ़ेस (यूआई) स्थिति खारिज करना तो सेव की गई स्थिति वापस नहीं आती. तय सीमा में सिस्टम से शुरू किया गया कोई बात नहीं.
सेटअप
फ़्रैगमेंट 1.2.0 से शुरू करना
या इसकी ट्रांज़िटिव डिपेंडेंसी
गतिविधि 1.1.0, आपके पास इन चीज़ों को स्वीकार करने का विकल्प है
आपके ViewModel
में निर्माता तर्क के रूप में SavedStateHandle
.
Kotlin
class SavedStateViewModel(private val state: SavedStateHandle) : ViewModel() { ... }
Java
public class SavedStateViewModel extends ViewModel { private SavedStateHandle state; public SavedStateViewModel(SavedStateHandle savedStateHandle) { state = savedStateHandle; } ... }
इसके बाद, अपने ViewModel
का इंस्टेंस, बिना किसी अतिरिक्त यूआरएल के वापस लाया जा सकता है
कॉन्फ़िगरेशन. डिफ़ॉल्ट ViewModel
फ़ैक्ट्री सही जानकारी देती है
आपके ViewModel
में SavedStateHandle
.
Kotlin
class MainFragment : Fragment() { val vm: SavedStateViewModel by viewModels() ... }
Java
class MainFragment extends Fragment { private SavedStateViewModel vm; public void onViewCreated(@NonNull View view, Bundle savedInstanceState) { vm = new ViewModelProvider(this).get(SavedStateViewModel.class); ... } ... }
कस्टम पैरामीटर बनाते समय
ViewModelProvider.Factory
उदाहरण के लिए, SavedStateHandle
AbstractSavedStateViewModelFactory
.
SafeStateHandle के साथ काम करना
SavedStateHandle
क्लास एक की-वैल्यू मैप है, जिसकी मदद से
के द्वारा सहेजी गई स्थिति में और उससे डेटा
set()
और get()
तरीकों का इस्तेमाल करना होगा.
SavedStateHandle
का इस्तेमाल करने पर, क्वेरी की वैल्यू तब तक बनी रहती है, जब तक प्रोसेस पूरी नहीं हो जाती,
यह पक्का करना कि उपयोगकर्ता को पहले और बाद में फ़िल्टर किए गए डेटा का एक ही सेट दिखे
मनोरंजन के लिए, मैन्युअल तौर पर सेव, पहले जैसा करने की ज़रूरत नहीं होती.
और उस वैल्यू को वापस ViewModel
पर भेज देता है.
SavedStateHandle
में अन्य तरीके भी हैं, जिनका इस्तेमाल इंटरैक्ट करते समय किया जा सकता है
की-वैल्यू मैप की मदद से:
contains(String key)
से यह जांचता है कि दी गई कुंजी के लिए कोई वैल्यू है या नहीं.remove(String key)
से दी गई कुंजी से वैल्यू हटाता है.keys()
- लौटाए गए प्रॉडक्टSavedStateHandle
में मौजूद सभी कुंजियां.
इसके अलावा, SavedStateHandle
से वैल्यू फिर से पाने के लिए इनका इस्तेमाल किया जा सकता है
मॉनिटर किया जा सकने वाला डेटा होल्डर. इस्तेमाल किए जा सकने वाले टाइप की सूची यहां दी गई है:
LiveData
SavedStateHandle
से वे मान वापस पाएं जिन्हें
LiveData
का इस्तेमाल करके मॉनिटर किया जा सकता है
getLiveData()
.
कुंजी की वैल्यू अपडेट होने पर, LiveData
को नई वैल्यू मिलती है. ज़्यादातर
अक्सर, मान को उपयोगकर्ता इंटरैक्शन के कारण सेट किया जाता है, जैसे
डेटा की सूची फ़िल्टर करें. इसके बाद, अपडेट की गई इस वैल्यू का इस्तेमाल इन कामों के लिए किया जा सकता है
LiveData
को पूरी तरह बदलें.
Kotlin
class SavedStateViewModel(private val savedStateHandle: SavedStateHandle) : ViewModel() { val filteredData: LiveData<List<String>> = savedStateHandle.getLiveData<String>("query").switchMap { query -> repository.getFilteredData(query) } fun setQuery(query: String) { savedStateHandle["query"] = query } }
Java
public class SavedStateViewModel extends ViewModel { private SavedStateHandle savedStateHandle; public LiveData<List<String>> filteredData; public SavedStateViewModel(SavedStateHandle savedStateHandle) { this.savedStateHandle = savedStateHandle; LiveData<String> queryLiveData = savedStateHandle.getLiveData("query"); filteredData = Transformations.switchMap(queryLiveData, query -> { return repository.getFilteredData(query); }); } public void setQuery(String query) { savedStateHandle.set("query", query); } }
स्टेटफ़्लो
SavedStateHandle
से वे मान वापस पाएं जिन्हें
StateFlow
का इस्तेमाल करके मॉनिटर किया जा सकता है
getStateFlow()
.
कुंजी की वैल्यू अपडेट करने पर, StateFlow
को नई वैल्यू मिलती है. ज़्यादातर
अक्सर, उपयोगकर्ता इंटरैक्शन के कारण मान सेट कर सकते हैं, जैसे दर्ज
क्वेरी का इस्तेमाल करें. इसके बाद, अपडेट की गई इस वैल्यू को बदला जा सकता है
दूसरे फ़्लो ऑपरेटर का इस्तेमाल करके.
Kotlin
class SavedStateViewModel(private val savedStateHandle: SavedStateHandle) : ViewModel() { val filteredData: StateFlow<List<String>> = savedStateHandle.getStateFlow<String>("query") .flatMapLatest { query -> repository.getFilteredData(query) } fun setQuery(query: String) { savedStateHandle["query"] = query } }
एक्सपेरिमेंटल कंपोज़ की सुविधा की स्थिति
lifecycle-viewmodel-compose
आर्टफ़ैक्ट, प्रयोग के तौर पर उपलब्ध कराता है
saveable
ऐसे एपीआई जो SavedStateHandle
और Compose के बीच इंटरऑपरेबिलिटी (दूसरे सिस्टम के साथ काम करने की सुविधा) की अनुमति देते हैं
Saver
ताकि कोई भी State
rememberSaveable
के ज़रिए सेव कर सकते हैं
पसंद के मुताबिक बनाए गए Saver
के साथ, SavedStateHandle
के साथ भी सेव किया जा सकता है.
Kotlin
class SavedStateViewModel(private val savedStateHandle: SavedStateHandle) : ViewModel() { var filteredData: List<String> by savedStateHandle.saveable { mutableStateOf(emptyList()) } fun setQuery(query: String) { withMutableSnapshot { filteredData += query } } }
काम करने वाली फ़ाइल के टाइप
SavedStateHandle
में रखे गए डेटा को
Bundle
के साथ ही, अन्य
savedInstanceState
गतिविधि या फ़्रैगमेंट के लिए.
सीधे तौर पर काम करने वाले टाइप
डिफ़ॉल्ट रूप से, आप set()
और get()
को SavedStateHandle
पर कॉल करके
Bundle
जैसा डेटा टाइप, जैसा कि नीचे दिखाया गया है:
टाइप/क्लास सहायता | कलेक्शन से जुड़ी सहायता |
double |
double[] |
int |
int[] |
long |
long[] |
String |
String[] |
byte |
byte[] |
char |
char[] |
CharSequence |
CharSequence[] |
float |
float[] |
Parcelable |
Parcelable[] |
Serializable |
Serializable[] |
short |
short[] |
SparseArray |
|
Binder |
|
Bundle |
|
ArrayList |
|
Size (only in API 21+) |
|
SizeF (only in API 21+) |
यदि कक्षा ऊपर दी गई सूची में से एक का विस्तार नहीं करती है, तो
@Parcelize
को जोड़कर पार्स किया जा सकने वाला क्लास
Kotlin एनोटेशन या लागू करना
Parcelable
सीधे.
पार्स नहीं की जा सकने वाली क्लास सेव की जा रही हैं
अगर कोई क्लास Parcelable
या Serializable
को लागू नहीं करती और
में बदलाव कर दिया है, तो
उस क्लास के इंस्टेंस को सीधे SavedStateHandle
में सेव करें.
इससे शुरुआत
लाइफ़साइकल 2.3.0-alpha03,
SavedStateHandle
आपको अपना खुद का ऑब्जेक्ट देकर किसी भी ऑब्जेक्ट को सेव करने की अनुमति देता है
आपका ऑब्जेक्ट को
Bundle
का इस्तेमाल
setSavedStateProvider()
तरीका. SavedStateRegistry.SavedStateProvider
एक ऐसा इंटरफ़ेस है जो
saveState()
तरीका, जो Bundle
वाला नतीजा दिखाता है, जिसमें वह स्थिति होती है जिसे आपको सेव करना है. टास्क कब शुरू होगा
SavedStateHandle
अपनी स्थिति सेव करने के लिए तैयार है और यह saveState()
को कॉल करता है
SavedStateProvider
से Bundle
को वापस पाने के लिए, और
जुड़ी हुई कुंजी के लिए Bundle
.
किसी ऐसे ऐप्लिकेशन के उदाहरण पर विचार करें जो Camera ऐप्लिकेशन से इमेज का अनुरोध करता है. इसके लिए,
ACTION_IMAGE_CAPTURE
इंटेंट, एक अस्थायी फ़ाइल पास कर रहा है, जहां कैमरे को
इमेज. TempFileViewModel
, लॉजिक बनाने के लिए लॉजिक को इकट्ठा करता है
अस्थायी फ़ाइल.
Kotlin
class TempFileViewModel : ViewModel() { private var tempFile: File? = null fun createOrGetTempFile(): File { return tempFile ?: File.createTempFile("temp", null).also { tempFile = it } } }
Java
class TempFileViewModel extends ViewModel { private File tempFile = null; public TempFileViewModel() { } @NonNull public File createOrGetTempFile() { if (tempFile == null) { tempFile = File.createTempFile("temp", null); } return tempFile; } }
यह पक्का करने के लिए कि गतिविधि की प्रोसेस बंद हो जाने पर अस्थायी फ़ाइल खो न जाए
और बाद में बहाल कर दिया जाएगा, TempFileViewModel
इन कामों के लिए SavedStateHandle
का इस्तेमाल कर सकता है
वह उस डेटा को सेव करके रखे. TempFileViewModel
अपना डेटा सेव कर सके, इसके लिए लागू करें
SavedStateProvider
और इसे सेवा देने वाली कंपनी के तौर पर, इस तारीख के SavedStateHandle
पर सेट करें
ViewModel
:
Kotlin
private fun File.saveTempFile() = bundleOf("path", absolutePath) class TempFileViewModel(savedStateHandle: SavedStateHandle) : ViewModel() { private var tempFile: File? = null init { savedStateHandle.setSavedStateProvider("temp_file") { // saveState() if (tempFile != null) { tempFile.saveTempFile() } else { Bundle() } } } fun createOrGetTempFile(): File { return tempFile ?: File.createTempFile("temp", null).also { tempFile = it } } }
Java
class TempFileViewModel extends ViewModel { private File tempFile = null; public TempFileViewModel(SavedStateHandle savedStateHandle) { savedStateHandle.setSavedStateProvider("temp_file", new TempFileSavedStateProvider()); } @NonNull public File createOrGetTempFile() { if (tempFile == null) { tempFile = File.createTempFile("temp", null); } return tempFile; } private class TempFileSavedStateProvider implements SavedStateRegistry.SavedStateProvider { @NonNull @Override public Bundle saveState() { Bundle bundle = new Bundle(); if (tempFile != null) { bundle.putString("path", tempFile.getAbsolutePath()); } return bundle; } } }
उपयोगकर्ता के वापस आने पर, File
का डेटा वापस लाने के लिए, temp_file
को वापस पाएं
SavedStateHandle
से Bundle
. यह वही Bundle
है जो इन्होंने उपलब्ध कराया है
saveTempFile()
, जिसमें ऐब्सलूट पाथ शामिल है. ऐब्सलूट पाथ से ऐसा हो सकता है
नया File
इंस्टैंशिएट करने के लिए इस्तेमाल किया जाएगा.
Kotlin
private fun File.saveTempFile() = bundleOf("path", absolutePath) private fun Bundle.restoreTempFile() = if (containsKey("path")) { File(getString("path")) } else { null } class TempFileViewModel(savedStateHandle: SavedStateHandle) : ViewModel() { private var tempFile: File? = null init { val tempFileBundle = savedStateHandle.get<Bundle>("temp_file") if (tempFileBundle != null) { tempFile = tempFileBundle.restoreTempFile() } savedStateHandle.setSavedStateProvider("temp_file") { // saveState() if (tempFile != null) { tempFile.saveTempFile() } else { Bundle() } } } fun createOrGetTempFile(): File { return tempFile ?: File.createTempFile("temp", null).also { tempFile = it } } }
Java
class TempFileViewModel extends ViewModel { private File tempFile = null; public TempFileViewModel(SavedStateHandle savedStateHandle) { Bundle tempFileBundle = savedStateHandle.get("temp_file"); if (tempFileBundle != null) { tempFile = TempFileSavedStateProvider.restoreTempFile(tempFileBundle); } savedStateHandle.setSavedStateProvider("temp_file", new TempFileSavedStateProvider()); } @NonNull public File createOrGetTempFile() { if (tempFile == null) { tempFile = File.createTempFile("temp", null); } return tempFile; } private class TempFileSavedStateProvider implements SavedStateRegistry.SavedStateProvider { @NonNull @Override public Bundle saveState() { Bundle bundle = new Bundle(); if (tempFile != null) { bundle.putString("path", tempFile.getAbsolutePath()); } return bundle; } @Nullable private static File restoreTempFile(Bundle bundle) { if (bundle.containsKey("path") { return File(bundle.getString("path")); } return null; } } }
टेस्ट मेंSaveStateHandle
SavedStateHandle
को डिपेंडेंसी के तौर पर इस्तेमाल करने वाले ViewModel
की जांच करने के लिए, बनाएं
SavedStateHandle
का एक नया इंस्टेंस, जिसकी ज़रूरी टेस्ट वैल्यू के साथ इसे पास किया गया है
इसे ViewModel
इंस्टेंस पर टेस्ट करें.
Kotlin
class MyViewModelTest { private lateinit var viewModel: MyViewModel @Before fun setup() { val savedState = SavedStateHandle(mapOf("someIdArg" to testId)) viewModel = MyViewModel(savedState = savedState) } }
अन्य संसाधन
ViewModel
के लिए सेव की गई स्थिति वाले मॉड्यूल के बारे में ज़्यादा जानकारी के लिए, देखें
इन संसाधनों को देखें.
कोड लैब
आपके लिए सुझाव
- ध्यान दें: JavaScript बंद होने पर लिंक टेक्स्ट दिखता है
- यूज़र इंटरफ़ेस (यूआई) की स्थितियां सेव करना
- ऑब्जेक्ट किए जा सकने वाले डेटा ऑब्जेक्ट के साथ काम करना
- डिपेंडेंसी के साथ ViewModels बनाना