📜  Android 中的首选项数据存储

📅  最后修改于: 2022-05-13 01:54:53.797000             🧑  作者: Mango

Android 中的首选项数据存储

Preference Data Store用于在 android 中永久存储数据。早些时候我们不得不共享首选项 同样,但由于它已被弃用,我们现在正在使用数据存储。下面给出了一个示例视频,以了解我们将在本文中做什么。请注意,我们将使用Kotlin语言来实现这个项目。

分步实施

第 1 步:创建一个新项目

想要一个更快节奏和更具竞争力的环境来学习 Android 的基础知识吗?
单击此处前往由我们的专家精心策划的指南,旨在让您立即做好行业准备!

要在 Android Studio 中创建新项目,请参阅如何在 Android Studio 中创建/启动新项目。注意选择Kotlin作为编程语言

第 2 步:在 build.gradle(app) 中添加依赖项

build.gradle(app)中添加 Data Store、Lifecycle 和 Coroutines 依赖项,然后单击立即同步按钮。

步骤 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 仓库在这里。