Android Jetpack- এর ViewModel অংশের জন্য সংরক্ষিত স্টেট মডিউল।
সেভিং UI স্টেটসে উল্লিখিত হিসাবে, ViewModel
অবজেক্টগুলি কনফিগারেশন পরিবর্তনগুলি পরিচালনা করতে পারে, তাই আপনাকে ঘূর্ণন বা অন্যান্য ক্ষেত্রে অবস্থা সম্পর্কে চিন্তা করতে হবে না। যাইহোক, যদি আপনাকে সিস্টেম-ইনিশিয়েটেড প্রসেস ডেথ পরিচালনা করতে হয়, আপনি ব্যাকআপ হিসাবে SavedStateHandle
API ব্যবহার করতে চাইতে পারেন।
UI স্টেট সাধারণত ViewModel
অবজেক্টে সংরক্ষিত বা রেফারেন্স করা হয় এবং ক্রিয়াকলাপ নয়, তাই onSaveInstanceState()
বা rememberSaveable
ব্যবহার করার জন্য কিছু বয়লারপ্লেট প্রয়োজন যা সংরক্ষিত স্টেট মডিউল আপনার জন্য পরিচালনা করতে পারে।
এই মডিউলটি ব্যবহার করার সময়, ViewModel
অবজেক্টগুলি তার কন্সট্রাক্টরের মাধ্যমে একটি SavedStateHandle
অবজেক্ট পায়। এই বস্তুটি একটি মূল-মান মানচিত্র যা আপনাকে সংরক্ষিত অবস্থায় এবং থেকে বস্তুগুলিকে লিখতে এবং পুনরুদ্ধার করতে দেয়। সিস্টেমের দ্বারা প্রক্রিয়াটি মারা যাওয়ার পরে এই মানগুলি বজায় থাকে এবং একই বস্তুর মাধ্যমে উপলব্ধ থাকে।
সংরক্ষিত অবস্থা আপনার টাস্ক স্ট্যাকের সাথে আবদ্ধ। আপনার টাস্ক স্ট্যাক চলে গেলে, আপনার সংরক্ষিত অবস্থাও চলে যায়। এটি ঘটতে পারে যখন একটি অ্যাপকে জোর করে বন্ধ করা হয়, সাম্প্রতিক মেনু থেকে অ্যাপটি সরানো হয় বা ডিভাইসটি রিবুট করা হয়। এই ধরনের ক্ষেত্রে, টাস্ক স্ট্যাক অদৃশ্য হয়ে যায় এবং আপনি সংরক্ষিত অবস্থায় তথ্য পুনরুদ্ধার করতে পারবেন না। ব্যবহারকারী-সূচিত UI রাজ্য বরখাস্ত পরিস্থিতিতে, সংরক্ষিত অবস্থা পুনরুদ্ধার করা হয় না। সিস্টেম-সূচিত পরিস্থিতিতে, এটা হয়.
সেটআপ
ফ্র্যাগমেন্ট 1.2.0 বা এর ট্রানজিটিভ ডিপেন্ডেন্সি অ্যাক্টিভিটি 1.1.0 দিয়ে শুরু করে, আপনি আপনার ViewModel
এর কনস্ট্রাক্টর আর্গুমেন্ট হিসেবে একটি SavedStateHandle
গ্রহণ করতে পারেন।
কোটলিন
class SavedStateViewModel(private val state: SavedStateHandle) : ViewModel() { ... }
জাভা
public class SavedStateViewModel extends ViewModel { private SavedStateHandle state; public SavedStateViewModel(SavedStateHandle savedStateHandle) { state = savedStateHandle; } ... }
তারপরে আপনি কোনও অতিরিক্ত কনফিগারেশন ছাড়াই আপনার ViewModel
একটি উদাহরণ পুনরুদ্ধার করতে পারেন। ডিফল্ট ViewModel
ফ্যাক্টরি আপনার ViewModel
এ উপযুক্ত SavedStateHandle
প্রদান করে।
কোটলিন
class MainFragment : Fragment() { val vm: SavedStateViewModel by viewModels() ... }
জাভা
class MainFragment extends Fragment { private SavedStateViewModel vm; public void onViewCreated(@NonNull View view, Bundle savedInstanceState) { vm = new ViewModelProvider(this).get(SavedStateViewModel.class); ... } ... }
একটি কাস্টম ViewModelProvider.Factory
উদাহরণ প্রদান করার সময়, আপনি AbstractSavedStateViewModelFactory
প্রসারিত করে SavedStateHandle
এর ব্যবহার সক্ষম করতে পারেন।
SavedStateHandle এর সাথে কাজ করা
SavedStateHandle
ক্লাস হল একটি মূল-মান মানচিত্র যা আপনাকে set()
এবং get()
পদ্ধতির মাধ্যমে সংরক্ষিত অবস্থায় এবং থেকে ডেটা লিখতে এবং পুনরুদ্ধার করতে দেয়।
SavedStateHandle
ব্যবহার করে, ক্যোয়ারী মানটি প্রক্রিয়ার মৃত্যু জুড়ে ধরে রাখা হয়, নিশ্চিত করে যে ব্যবহারকারী ম্যানুয়ালি সংরক্ষণ, পুনরুদ্ধার এবং সেই মানটিকে ViewModel
এ ফেরত পাঠানোর প্রয়োজনীয় কার্যকলাপ বা খণ্ড ছাড়াই বিনোদনের আগে এবং পরে ফিল্টার করা ডেটার একই সেট দেখতে পান।
SavedStateHandle
অন্যান্য পদ্ধতিও রয়েছে যা আপনি একটি মূল-মান মানচিত্রের সাথে ইন্টারঅ্যাক্ট করার সময় আশা করতে পারেন:
-
contains(String key)
- প্রদত্ত কীটির জন্য একটি মান আছে কিনা তা পরীক্ষা করে। -
remove(String key)
- প্রদত্ত কীটির মান সরিয়ে দেয়। -
keys()
-SavedStateHandle
মধ্যে থাকা সমস্ত কী ফেরত দেয়।
উপরন্তু, আপনি একটি পর্যবেক্ষণযোগ্য ডেটা ধারক ব্যবহার করে SavedStateHandle
থেকে মান পুনরুদ্ধার করতে পারেন। সমর্থিত প্রকারের তালিকা হল:
লাইভডেটা
getLiveData()
ব্যবহার করে পর্যবেক্ষণযোগ্য একটি LiveData
এ মোড়ানো SavedStateHandle
থেকে মান পুনরুদ্ধার করুন। যখন কী এর মান আপডেট করা হয়, তখন LiveData
নতুন মান পায়। প্রায়শই, ব্যবহারকারীর ইন্টারঅ্যাকশনের কারণে মান সেট করা হয়, যেমন ডেটার একটি তালিকা ফিল্টার করার জন্য একটি ক্যোয়ারী প্রবেশ করানো। এই আপডেট করা মানটি তখন LiveData
রূপান্তর করতে ব্যবহার করা যেতে পারে।
কোটলিন
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 } }
জাভা
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); } }
স্টেটফ্লো
getStateFlow()
ব্যবহার করে পর্যবেক্ষণযোগ্য একটি StateFlow
এ মোড়ানো SavedStateHandle
থেকে মান পুনরুদ্ধার করুন। আপনি যখন কী এর মান আপডেট করেন, StateFlow
নতুন মান পায়। প্রায়শই, আপনি ব্যবহারকারীর ইন্টারঅ্যাকশনের কারণে মান সেট করতে পারেন, যেমন ডেটার একটি তালিকা ফিল্টার করতে একটি ক্যোয়ারী প্রবেশ করান। তারপরে আপনি অন্যান্য ফ্লো অপারেটর ব্যবহার করে এই আপডেট করা মানটিকে রূপান্তর করতে পারেন।
কোটলিন
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
API সরবরাহ করে যা SavedStateHandle
এবং Compose's Saver
মধ্যে আন্তঃকার্যযোগ্যতার অনুমতি দেয় যাতে আপনি একটি কাস্টম Saver
সাথে rememberSaveable
এর মাধ্যমে সংরক্ষণ করতে পারেন এমন যেকোন State
SavedStateHandle
এর মাধ্যমে সংরক্ষণ করা যেতে পারে।
কোটলিন
class SavedStateViewModel(private val savedStateHandle: SavedStateHandle) : ViewModel() { var filteredData: List<String> by savedStateHandle.saveable { mutableStateOf(emptyList()) } fun setQuery(query: String) { withMutableSnapshot { filteredData += query } } }
সমর্থিত প্রকার
একটি SavedStateHandle
মধ্যে রাখা ডেটা অ্যাক্টিভিটি বা ফ্র্যাগমেন্টের জন্য বাকি savedInstanceState
সহ একটি Bundle
হিসাবে সংরক্ষণ এবং পুনরুদ্ধার করা হয়।
সরাসরি সমর্থিত প্রকার
ডিফল্টরূপে, আপনি একটি SavedStateHandle
set()
কল করতে পারেন এবং একটি Bundle
মতো একই ডেটা প্রকারের জন্য get()
, যেমনটি নীচে দেখানো হয়েছে:
টাইপ/ক্লাস সাপোর্ট | অ্যারে সমর্থন |
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
আপনাকে setSavedStateProvider()
পদ্ধতি ব্যবহার করে Bundle
হিসাবে আপনার অবজেক্টকে সংরক্ষণ এবং পুনরুদ্ধার করার জন্য আপনার নিজস্ব যুক্তি প্রদান করে যেকোনো বস্তু সংরক্ষণ করতে দেয়। SavedStateRegistry.SavedStateProvider
হল একটি ইন্টারফেস যা একটি একক saveState()
পদ্ধতি সংজ্ঞায়িত করে যা একটি Bundle
প্রদান করে যেখানে আপনি যে রাজ্যটি সংরক্ষণ করতে চান। যখন SavedStateHandle
তার অবস্থা সংরক্ষণ করার জন্য প্রস্তুত হয়, তখন এটি saveState()
SavedStateProvider
থেকে Bundle
পুনরুদ্ধার করতে কল করে এবং সংশ্লিষ্ট কীটির জন্য Bundle
সংরক্ষণ করে।
একটি অ্যাপের উদাহরণ বিবেচনা করুন যেটি ক্যামেরা অ্যাপ থেকে ACTION_IMAGE_CAPTURE
উদ্দেশ্যের মাধ্যমে একটি চিত্রের জন্য অনুরোধ করে, যেখানে ক্যামেরাটি ছবিটি সংরক্ষণ করবে তার জন্য একটি অস্থায়ী ফাইলে পাস করে৷ TempFileViewModel
সেই অস্থায়ী ফাইলটি তৈরি করার জন্য যুক্তিকে এনক্যাপসুলেট করে।
কোটলিন
class TempFileViewModel : ViewModel() { private var tempFile: File? = null fun createOrGetTempFile(): File { return tempFile ?: File.createTempFile("temp", null).also { tempFile = it } } }
জাভা
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
প্রয়োগ করুন এবং ViewModel
এর SavedStateHandle
এ প্রদানকারী হিসেবে সেট করুন:
কোটলিন
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 } } }
জাভা
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
ডেটা পুনরুদ্ধার করতে, SavedStateHandle
থেকে temp_file
Bundle
পুনরুদ্ধার করুন। এটি saveTempFile()
দ্বারা প্রদত্ত একই Bundle
যা পরম পাথ ধারণ করে। পরম পাথ তারপর একটি নতুন File
ইনস্ট্যান্ট করতে ব্যবহার করা যেতে পারে।
কোটলিন
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 } } }
জাভা
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; } } }
টেস্টে সংরক্ষিত স্টেটহ্যান্ডেল
একটি নির্ভরতা হিসাবে একটি SavedStateHandle
গ্রহণ করে এমন একটি ViewModel
পরীক্ষা করতে, এটির প্রয়োজনীয় পরীক্ষার মানগুলির সাথে SavedStateHandle
এর একটি নতুন উদাহরণ তৈরি করুন এবং আপনি যে ViewModel
পরীক্ষা করছেন সেটিতে পাস করুন৷
কোটলিন
class MyViewModelTest { private lateinit var viewModel: MyViewModel @Before fun setup() { val savedState = SavedStateHandle(mapOf("someIdArg" to testId)) viewModel = MyViewModel(savedState = savedState) } }
অতিরিক্ত সম্পদ
ViewModel
এর জন্য সংরক্ষিত স্টেট মডিউল সম্পর্কে আরও তথ্যের জন্য, নিম্নলিখিত সংস্থানগুলি দেখুন।
কোডল্যাব
{% শব্দার্থে %}আপনার জন্য প্রস্তাবিত
- দ্রষ্টব্য: জাভাস্ক্রিপ্ট বন্ধ থাকলে লিঙ্ক টেক্সট প্রদর্শিত হয়
- UI রাজ্যগুলি সংরক্ষণ করুন
- পর্যবেক্ষণযোগ্য ডেটা অবজেক্টের সাথে কাজ করুন
- নির্ভরতা সহ ViewModels তৈরি করুন