Android 中的首选项数据存储
Preference Data Store用于在 android 中永久存储数据。早些时候我们不得不共享首选项 同样,但由于它已被弃用,我们现在正在使用数据存储。下面给出了一个示例视频,以了解我们将在本文中做什么。请注意,我们将使用Kotlin语言来实现这个项目。
分步实施
第 1 步:创建一个新项目
要在 Android Studio 中创建新项目,请参阅如何在 Android Studio 中创建/启动新项目。注意选择Kotlin作为编程语言
第 2 步:在 build.gradle(app) 中添加依赖项
在build.gradle(app)中添加 Data Store、Lifecycle 和 Coroutines 依赖项,然后单击立即同步按钮。
// Preferences DataStore
implementation “androidx.datastore:datastore-preferences:1.0.0-alpha01”
// Lifecycle components
implementation “androidx.lifecycle:lifecycle-livedata-ktx:2.2.0”
implementation “androidx.lifecycle:lifecycle-extensions:2.2.0”
implementation “androidx.lifecycle:lifecycle-common-java8:2.2.0”
implementation “androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0”
// Kotlin coroutines components
implementation “org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.4.10”
api “org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.1”
api “org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.1”
步骤 3:使用 activity_main.xml 文件
转到activity_main.xml文件并参考以下代码。下面是activity_main.xml文件的代码。这是应用程序中使用的基本布局。
XML
Kotlin
import android.content.Context
import androidx.datastore.preferences.createDataStore
import androidx.datastore.preferences.edit
import androidx.datastore.preferences.preferencesKey
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
class UserManager(context: Context) {
// Create the dataStore and give it a name same as shared preferences
private val dataStore = context.createDataStore(name = "user_prefs")
// Create some keys we will use them to store and retrieve the data
companion object {
val USER_AGE_KEY = preferencesKey("USER_AGE")
val USER_NAME_KEY = preferencesKey("USER_NAME")
}
// Store user data
// refer to the data store and using edit
// we can store values using the keys
suspend fun storeUser(age: Int, name: String) {
dataStore.edit {
it[USER_AGE_KEY] = age
it[USER_NAME_KEY] = name
// here it refers to the preferences we are editing
}
}
// Create an age flow to retrieve age from the preferences
// flow comes from the kotlin coroutine
val userAgeFlow: Flow = dataStore.data.map {
it[USER_AGE_KEY] ?: 0
}
// Create a name flow to retrieve name from the preferences
val userNameFlow: Flow = dataStore.data.map {
it[USER_NAME_KEY] ?: ""
}
}
Kotlin
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.asLiveData
import androidx.lifecycle.observe
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
class MainActivity : AppCompatActivity() {
lateinit var etName: EditText
lateinit var etAge: EditText
lateinit var tvName: TextView
lateinit var tvAge: TextView
lateinit var saveButton: Button
lateinit var userManager: UserManager
var age = 0
var name = ""
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
etName = findViewById(R.id.et_name)
etAge = findViewById(R.id.et_age)
tvName = findViewById(R.id.tv_name)
tvAge = findViewById(R.id.tv_age)
saveButton = findViewById(R.id.btn_save)
// Get reference to our userManager class
userManager = UserManager(this)
// this function saves the data to
// preference data store on click of
// save Button
buttonSave()
// this function retrieves the saved data
// as soon as they are stored and even
// after app is closed and started again
observeData()
}
private fun buttonSave() {
// Gets the user input and saves it
saveButton.setOnClickListener {
name = etName.text.toString()
age = etAge.text.toString().toInt()
// Stores the values
// Since the storeUser function of UserManager
// class is a suspend function
// So this has to be done in a coroutine scope
GlobalScope.launch {
userManager.storeUser(age, name)
}
}
}
private fun observeData() {
// Updates age
// every time user age changes it will be observed by userAgeFlow
// here it refers to the value returned from the userAgeFlow function
// of UserManager class
this.userManager.userAgeFlow.asLiveData().observe(this) {
age = it
tvAge.text = it.toString()
}
// Updates name
// every time user name changes it will be observed by userNameFlow
// here it refers to the value returned from the usernameFlow function
// of UserManager class
userManager.userNameFlow.asLiveData().observe(this) {
name = it
tvName.text = it.toString()
}
}
}
第 4 步:使用 UserManager.kt 类
创建一个新的 kotlin 类并将其命名为UserManager ,该类包含用于从首选项数据存储中保存和检索数据的代码。代码中添加了注释以更详细地理解代码。
科特林
import android.content.Context
import androidx.datastore.preferences.createDataStore
import androidx.datastore.preferences.edit
import androidx.datastore.preferences.preferencesKey
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
class UserManager(context: Context) {
// Create the dataStore and give it a name same as shared preferences
private val dataStore = context.createDataStore(name = "user_prefs")
// Create some keys we will use them to store and retrieve the data
companion object {
val USER_AGE_KEY = preferencesKey("USER_AGE")
val USER_NAME_KEY = preferencesKey("USER_NAME")
}
// Store user data
// refer to the data store and using edit
// we can store values using the keys
suspend fun storeUser(age: Int, name: String) {
dataStore.edit {
it[USER_AGE_KEY] = age
it[USER_NAME_KEY] = name
// here it refers to the preferences we are editing
}
}
// Create an age flow to retrieve age from the preferences
// flow comes from the kotlin coroutine
val userAgeFlow: Flow = dataStore.data.map {
it[USER_AGE_KEY] ?: 0
}
// Create a name flow to retrieve name from the preferences
val userNameFlow: Flow = dataStore.data.map {
it[USER_NAME_KEY] ?: ""
}
}
步骤 5:使用 MainActivity.kt 文件
转到MainActivity.kt文件并参考以下代码。下面是MainActivity.kt文件的代码。代码中添加了注释以更详细地理解代码。
科特林
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.asLiveData
import androidx.lifecycle.observe
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
class MainActivity : AppCompatActivity() {
lateinit var etName: EditText
lateinit var etAge: EditText
lateinit var tvName: TextView
lateinit var tvAge: TextView
lateinit var saveButton: Button
lateinit var userManager: UserManager
var age = 0
var name = ""
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
etName = findViewById(R.id.et_name)
etAge = findViewById(R.id.et_age)
tvName = findViewById(R.id.tv_name)
tvAge = findViewById(R.id.tv_age)
saveButton = findViewById(R.id.btn_save)
// Get reference to our userManager class
userManager = UserManager(this)
// this function saves the data to
// preference data store on click of
// save Button
buttonSave()
// this function retrieves the saved data
// as soon as they are stored and even
// after app is closed and started again
observeData()
}
private fun buttonSave() {
// Gets the user input and saves it
saveButton.setOnClickListener {
name = etName.text.toString()
age = etAge.text.toString().toInt()
// Stores the values
// Since the storeUser function of UserManager
// class is a suspend function
// So this has to be done in a coroutine scope
GlobalScope.launch {
userManager.storeUser(age, name)
}
}
}
private fun observeData() {
// Updates age
// every time user age changes it will be observed by userAgeFlow
// here it refers to the value returned from the userAgeFlow function
// of UserManager class
this.userManager.userAgeFlow.asLiveData().observe(this) {
age = it
tvAge.text = it.toString()
}
// Updates name
// every time user name changes it will be observed by userNameFlow
// here it refers to the value returned from the usernameFlow function
// of UserManager class
userManager.userNameFlow.asLiveData().observe(this) {
name = it
tvName.text = it.toString()
}
}
}
输出:
Github 仓库在这里。