StateStore Android Jetpack-এর অংশ।
StateStore হল একটি টাইপ-সেফ কন্টেনার যা আপনার অ্যাপ জুড়ে Compose State হিসেবে শেয়ার করা অ্যাপ্লিকেশন স্টেট স্টোর করে এবং দেখায়।
উদাহরণ
অ্যাপ্লিকেশন-স্কোপড StateStore তৈরি করে, আপনি একই প্রসেসের মধ্যে অ্যাপ্লিকেশন কম্পোনেন্টের মধ্যে
স্টেট শেয়ার করতে পারবেন:
- একাধিক অ্যাক্টিভিটি: আপনার অ্যাপ যদি একসাথে একাধিক অ্যাক্টিভিটি
দেখায় (যেমন, ইমেল ক্লায়েন্টে ইনবক্স অ্যাক্টিভিটি ও এডিটর অ্যাক্টিভিটি)
অথবা এমন কোনও অ্যাক্টিভিটি থাকে যা মাল্টি-ইনস্ট্যান্স (যেমন, ডকুমেন্ট ভিউয়ার অ্যাক্টিভিটি)
সাপোর্ট করে, তাহলে আপনি তাদের মধ্যে তথ্য শেয়ার করতে
StateStoreব্যবহার করতে পারেন। - অ্যাক্টিভিটি ও পরিষেবা: কোনও অ্যাক্টিভিটি ও ব্যাকগ্রাউন্ড
CarAppServiceবা AppFunction-এর মধ্যে স্ট্যাটাস সিঙ্ক করুন। - অ্যাক্টিভিটি এবং কন্টেন্ট প্রোভাইডার বা উইজেট: কোনও অ্যাক্টিভিটি এবং হোম স্ক্রিন উইজেটের মধ্যে স্ট্যাটাস শেয়ার করুন।
যদি কোনও সিঙ্গলটনের শুধুমাত্র ইন-মেমরি State<T>-এর প্রয়োজন হয়, যেখানে কীড লুকআপ বা
DataStore-ব্যাকড প্রসেস-ডেথ রিস্টোরেশনের প্রয়োজন নেই, তাহলে আপনি সরাসরি সিঙ্গলটনে mutableStateOf
প্রপার্টি এক্সপোজ করতে পারেন। আপনার অ্যাপ জুড়ে স্টেট API-এর তুলনা করতে, আপনার আর্কিটেকচার জুড়ে সঠিক স্টেট API বেছে নিন দেখুন।
API ওভারভিউ
androidx.appstate.statestore প্যাকেজে StateStore এবং
StateStoreKey ক্লাস প্রদান করা হয়:
package androidx.appstate.statestore
import androidx.compose.runtime.State
import kotlinx.serialization.Serializable
public class StateStore {
public val keys: Set<StateStoreKey<*>>
public fun <T> getState(
stateKey: StateStoreKey<T>,
defaultValue: T = stateKey.defaultValue,
): State<T>
public fun <T> setState(stateKey: StateStoreKey<T>, value: T)
public inline fun <T> updateState(
stateKey: StateStoreKey<T>,
defaultValue: T = stateKey.defaultValue,
update: (T) -> T,
)
}
@Serializable
public open class StateStoreKey<T>(
public val defaultValue: T,
)
আপনার রাজ্য উল্লেখ করুন
ভ্যালু স্টোর ও রিট্রিভ করার সময় টাইপ নিরাপত্তা নিশ্চিত করতে, StateStore
StateStoreKey ক্লাস ব্যবহার করে ভ্যালু রিড ও রাইট করার জন্য ব্যবহৃত কীগুলি সংজ্ঞায়িত করে। StateStoreKey সংজ্ঞা private বা internal ম্যানেজার, রিপোজিটরি
বা সেই স্লাইস অফ স্টেটের মালিকানা আছে এমন মডিউলে রাখুন:
@Serializable sealed interface FocusSession { @Serializable data object Idle : FocusSession @Serializable data class Running( val taskId: String, val endTimeMillis: Long, ) : FocusSession @Serializable data class Paused( val taskId: String, val remainingMillis: Long, ) : FocusSession } @Serializable private data object FocusSessionKey : StateStoreKey<FocusSession>(defaultValue = FocusSession.Idle)
StateStore ইনস্ট্যান্স তৈরি ও ইনজেক্ট করুন
StateStore হল একটি সাধারণ ক্লাস যা আপনি অ্যাপ্লিকেশন বা মডিউল স্কোপে একবার ইনস্ট্যান্টিয়েট করেন (যেমন, আপনার Application ক্লাস বা ডিপেন্ডেন্সি ইনজেকশন মডিউলে) এবং ম্যানেজার বা রিপোজিটরিতে ইনজেক্ট করেন যা স্টেট রিড ও রাইট করে, UI ক্লাসে সরাসরি StateStore দেখানোর পরিবর্তে:
// Instantiate at the application or DI module level val stateStore = StateStore() // Inject into managers or repositories that encapsulate their own keys class FocusSessionManager( private val stateStore: StateStore, )
স্ট্যাটাস দেখুন ও লিখুন
আপনার ম্যানেজার বা রিপোজিটরির মধ্যে, আপনার ব্যক্তিগত StateStoreKey সংজ্ঞা ব্যবহার করে ইনজেক্ট করা StateStore-এ ভ্যালু পড়ুন, লিখুন এবং আপডেট করুন এবং কলারদের জন্য শুধুমাত্র পড়ার জন্য State<T> প্রপার্টি এবং মিউটেশন ফাংশন প্রকাশ করুন।
স্ট্যাটাস পড়ুন
State<T> অবজেক্ট
পুনরুদ্ধার করতে getState(stateKey, defaultValue) ব্যবহার করুন। 'কী' এখনও ইনিশিয়ালাইজ করা না হলে, StateStore এটি defaultValue প্যারামিটার দিয়ে পপুলেট করে, যা ডিফল্ট হিসেবে stateKey.defaultValue (অথবা আপনি পপুলেট না করা 'কী' ইনিশিয়ালাইজ করার সময় কাস্টম defaultValue পাস করতে পারেন)। যেহেতু
getState একটি State<T>, ViewModels, UI কম্পোজেবল, উইজেট এবং
transform ব্লক রিটার্ন করে, তাই ম্যানেজারের প্রপার্টি
প্রতিক্রিয়াশীলভাবে পড়তে পারে:
class FocusSessionManager( private val stateStore: StateStore, ) { val session: State<FocusSession> = stateStore.getState(FocusSessionKey) } class FocusTimerViewModel( focusSessionManager: FocusSessionManager, ) : ViewModel() { val session: State<FocusSession> = focusSessionManager.session } @Composable fun FocusBanner(viewModel: FocusTimerViewModel = viewModel()) { // Reads state reactively; recomposes when FocusSessionKey updates when (val session = viewModel.session.value) { FocusSession.Idle -> Text(text = "No active focus session") is FocusSession.Running -> Text(text = "Focusing on ${session.taskId}") is FocusSession.Paused -> Text(text = "Paused: ${session.taskId}") } }
রাজ্য লিখুন
আপনার ম্যানেজারের মধ্যে setState(stateKey, value) ব্যবহার করে কোনও কী-এর সাথে যুক্ত ভ্যালু শুরু করুন বা
পরিবর্তন করুন:
class FocusSessionManager( private val stateStore: StateStore, ) { val session: State<FocusSession> = stateStore.getState(FocusSessionKey) fun startFocus(taskId: String, endTimeMillis: Long) { stateStore.setState( FocusSessionKey, FocusSession.Running( taskId = taskId, endTimeMillis = endTimeMillis, ), ) } fun endFocus() { stateStore.setState(FocusSessionKey, FocusSession.Idle) } }
রাজ্য আপডেট করুন
বর্তমান ভ্যালুর উপর ভিত্তি করে কোনও স্টেট আপডেট করতে হলে, updateState ব্যবহার করুন।
এটি বর্তমান ভ্যালু ফিরিয়ে আনে (অথবা সেট করা না থাকলে ডিফল্ট ভ্যালু ব্যবহার করে) এবং আপনার আপডেট ল্যাম্বডা প্রয়োগ করে:
class FocusSessionManager( private val stateStore: StateStore, ) { val session: State<FocusSession> = stateStore.getState(FocusSessionKey) fun pauseFocus(nowMillis: Long) { stateStore.updateState(FocusSessionKey) { current -> if (current is FocusSession.Running) { FocusSession.Paused( taskId = current.taskId, remainingMillis = (current.endTimeMillis - nowMillis) .coerceAtLeast(0L), ) } else { current } } } fun resumeFocus(nowMillis: Long) { stateStore.updateState(FocusSessionKey) { current -> if (current is FocusSession.Paused) { FocusSession.Running( taskId = current.taskId, endTimeMillis = nowMillis + current.remainingMillis, ) } else { current } } } }
ইন্টিগ্রেশন
প্রসেস বন্ধ করা এবং অ্যাপ রিস্টার্ট করার সময় স্ট্যাটাস বজায় রাখতে ও
রিস্টোর করতে StateStore, Jetpack DataStore-এর সাথে ইন্টিগ্রেট করে।
DataStore
androidx.appstate.statestore:statestore-datastore আর্টিফ্যাক্ট আপনাকে
শেয়ার করা StateStore ইনস্ট্যান্সে একবার পারসিস্টেন্স কনফিগার করতে দেয় যাতে যেকোনও
ম্যানেজারের পারসিস্টেড 'কী' অটোমেটিক সেভ হয় এবং DataStore ব্যবহার করে ডিস্ক থেকে রিস্টোর হয়।
androidx.appstate.datastore প্যাকেজ নিম্নলিখিত API প্রদান করে:
package androidx.appstate.datastore
import androidx.appstate.statestore.StateStore
import androidx.datastore.core.DataStore
import kotlinx.coroutines.CoroutineScope
public interface PersistToDataStore
public suspend fun StateStore.syncToDataStore(
path: String,
coroutineScope: CoroutineScope,
)
public suspend fun StateStore.syncToDataStore(
dataStore: DataStore<StateStorePreferences>,
)
PersistToDataStoreপ্রয়োগ করুন:PersistToDataStoreইন্টারফেস প্রয়োগ করে যেসবStateStoreKeyবজায় রাখা উচিত সেগুলি চিহ্নিত করুন:
@Serializable private data object FocusSessionKey : StateStoreKey<FocusSession>(defaultValue = FocusSession.Idle), PersistToDataStore
- DataStore-এ
StateStoreবাইন্ড করুন: আপনার শেয়ার করাStateStoreইনস্ট্যান্স সেট-আপ করার সময় একবারsyncToDataStoreকল করুন (যেমন, আপনারApplicationক্লাস বা ডিপেন্ডেন্সি ইনজেকশন মডিউলে)। যেহেতুsyncToDataStoreহল একটিsuspendফাংশন যা ডিস্ক থেকে সেভ করা ভ্যালু রিস্টোর করতে এবং প্রদত্তcoroutineScope-এ ভবিষ্যতের পরিবর্তনগুলি সেভ করা চালিয়ে যেতে অনির্দিষ্টকালের জন্য সাসপেন্ড করে, তাই এটিকেlaunch-এর মধ্যে কল করুন এবং আপনার অ্যাপ্লিকেশন-লেভেলCoroutineScopeপাস করুন। চালু করার সময়,getStateপ্রথমে মেমরিতেdefaultValueফিরিয়ে আনে এবং ডিস্ক থেকে DataStore-এর রিডিং শেষ হলেStateআপডেট করে:
class ProductivityApplication : Application() { val applicationScope = CoroutineScope(SupervisorJob() + Dispatchers.Default) val stateStore = StateStore().also { store -> // Restore saved values and automatically persist future changes // for all PersistToDataStore keys across managers applicationScope.launch { store.syncToDataStore( path = dataStoreFile("statestore.json").absolutePath, coroutineScope = applicationScope, ) } } val focusSessionManager = FocusSessionManager(stateStore) }
DataStore পারসিসটেন্স সংক্রান্ত নির্দেশিকা
যেহেতু syncToDataStore সিরিয়ালাইজ করে এবং যখনই PersistToDataStore কী-এর ভ্যালু পরিবর্তন হয় তখনই ডিস্কে লেখে, তাই কী এবং কখন পারসিস্ট করতে হবে তা বেছে নেওয়ার সময় এইসব নির্দেশিকা অনুসরণ করুন:
- প্রতিটি টাইমার টিকের পরিবর্তে শুরু বা শেষের টাইমস্ট্যাম্প সেভ করুন: টাইমার বা
প্লেব্যাক প্রগ্রেসের জন্য, প্রতি সেকেন্ড বা ফ্রেমে
PersistToDataStoreকী আপডেট করার পরিবর্তে একটি স্থিতিশীল রেফারেন্স ভ্যালু (যেমনendTimeMillisবাstartedAtMillis) বজায় রাখুন এবং UI-তে লাইভ অতিবাহিত বা অবশিষ্ট ডিসপ্লে গণনা করুন। - পারসিস্টেড কী আপডেট করার আগে ব্যবহারকারীর দ্রুত ইনপুট ডিবাউন্স করুন: টেক্সট
ড্রাফ্ট, সার্চ কোয়েরি বা স্লাইডারের জন্য, ইন-মেমরি
MutableState(বাStateStoreKeyযাPersistToDataStoreপ্রয়োগ করে না) -এ অবিলম্বে ইনপুট হোল্ড করুন এবং ইনপুট সেটেল হওয়ার পরে পারসিস্টেডStateStoreKey-এ শুধুমাত্রsetStateকল করুন। - পারসিস্টেড 'কী' লাইটওয়েট রাখুন: প্রতিটি আপডেটে একটি ফাইলে
StateStore-এর সবPersistToDataStore'কী' একসাথে সিরিয়ালাইজ করা হয়। কমপ্যাক্ট সেশন স্টেট—যেমন অ্যাক্টিভ আইডি, ফিল্টার সিলেকশন বা প্রোগ্রেসে থাকা ফর্ম ড্রাফ্ট—সেভ করে রাখুন এবং Room-এ বড় কালেকশন বা কোয়েরি করা যায় এমন ডেটাসেট রাখুন।