خدافظی با SharedPreferences - آموزش DataStore در اندروید
دیتا استور چیه؟
دیتا استور(DataStore) کامپوننت جدید Jetpack که قرار جایگزین SharedPreferences بشه، طبیعتا نو که بیاد به بازار یه سری ویژگی های جدید داره، بهترین ویژگی که دیتا استور نسبت به شردپرفرنسز داره اینه که خوندن و نوشتن دیتا به صورت Async و با Flow که کامپوننتی از Kotlin Coroutines هست انجام میشه. چندتا نکته که قبل از ادامه دادن باید بدونید اینه که:
- دیتا استور در این زمان که این پست نوشته میشه تو حالت آلفا قرار داره که برای استفاده در پروداکشن مناسب نیست.
- قراره ما با کاتلین کد بزنیم
- ما از Kotlin Coroutines استفاده میکنیم(خیلی سطح پایین)
- همچنین از Kotlin Extension هم استفاده شده
- برای UI برنامه از Jetpack Compose استفاده شده
چطور ازش استفاده کنیم
مرحله اول - کتابخونه رو به پروژه اضافه میکنیم:
implementation "androidx.datastore:datastore-preferences:1.0.0-alpha02"
مرحله دوم - ساخت یک نمونه از دیتا استور:
private val dataStore by lazy { context.createDataStore(name = "data_store") }
مرحله سوم - خوندن و نوشتن:
دیتا استور هم مثل شردپرفرنسز داده ها رو به صورت key-value سازماندهی میکنه، اما موضوع برای دیتا استور یکم فرق داره اونم اینه که مثل شردپرفرنسز key ها به صورت string نیستن بلکه اونا باید از نوع Preferences.Key باشن(جلوتر مسئله روشنتر میشه) و موضوع دیگه ای هم که هست اگه بخوایم دیتایی رو توی دیتا استور ذخیره کنیم حتما باید از کوروتین کاتلین استفاده کینم، که در ساده ترین حالت فرآیند ذخیره کردن به شکل زیر هست:
GlobalScope.launch {
val TEXT_KEY = preferencesKey<String>("text")
dataStore.edit {
it[TEXT_KEY] = "This is just a simple text"
}
}
درست مثل شردپرفرنسز تو خط دوم یک کلید برای ذخیره کردن دیتامون ساختیم به اسم TEXT_KEY و خط های بعدی دیتا رو توی دیتا استور ذخیره میکنه
وقتی بخوایم داده هایی رو که قبلا ذخیره شدن رو از دیتا استور بخونیم، ما اون دیتا رو در قالب Flow دریافت میکنیم مثل کد زیر:
val text: Flow<String> = dataStore.data.map { data ->
data[key] ?: "Default value" // if the data is null we'll get the "Default value" text
}
text.collect { data ->
println("data is: $data")
}
درسته یکم عجیب غریب به نظر میاد برای همین همونطوری که بالاتر قید شد برای اینکه کار با دیتا استور راحتتر و خوانایی کدها بالاتر بره یه سری Extension Function به سورسکدمون اضافه کردیم
@InternalCoroutinesApi
fun <T> DataStore<Preferences>.liveData(key: Preferences.Key<T>, defaultValue: T): LiveData<T> =
data.map {
it[key] ?: defaultValue // if the data is null we'll get the defaultValue
}.asLiveData(IO)
fun <T> DataStore<Preferences>.saveData(data: Pair<Preferences.Key<T>, T>) = GlobalScope.launch {
edit {
it[data.first] = data.second
}
}
فانکشن اول دیتای ذخیره شده تو دیتا استور رو به صورت LiveData به ما میده که نهایتا نحوه خوندن از دیتا استور رو آسونتر میکنه:
val textLiveData: LiveData<String> = dataStore.liveData(TEXT_KEY, "not specified yet") // "not specified yet" is the default value
همینطور نحوه استفاده از فانکشن دوم:
dataStore.saveData(TEXT_KEY to "This text is gonna be saved in data store")
در نهایت کد کامل اکتیویتی:
class MainActivity : AppCompatActivity() {
private val dataStore by lazy { createDataStore(name = "data_store") }
@InternalCoroutinesApi
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val textLiveData: LiveData<String> = dataStore.liveData(TEXT_KEY, "null")
setContent {
AppScreen(
textLiveData = textLiveData,
onSaveClicked = { saveText(it) }
)
}
}
private fun saveText(value: String) = dataStore.saveData(TEXT_KEY to value)
companion object {
private val TEXT_KEY = preferencesKey<String>("text")
}
میتونید کد کامل رو از گیت دریافت کنید
مطلبی دیگر از این انتشارات
فواید استفاده از معماری در برنامه نویسی
مطلبی دیگر از این انتشارات
لی اوت در اندروید ۱۱ : آشنایی با ConstraintLayout
مطلبی دیگر از این انتشارات
مفاهیم Functional programming در کاتلین