如何在 kotlin 的 SharedPreferences 中使用 mutableSetOf

How to use mutableSetOf in SharedPreferences in kotlin

嘿,我在 Android Kotlin 的 SharedPreferences 工作。我在 SharedPreferences 的 mutableSetOf 中设置值。我这样做没有任何错误,但问题是我的值存储在单个集合项目中。我不明白为什么这会导致问题。但是在那个时候储存价值之后,我也在阅读价值。它向我展示了新数据的价值,如果签入 /data/data/com.example.activityexample/shared_prefs/vivek_pref.xml,它只会向我展示单组数据。谁能指导我如何正确使用。

MainActivity.kt

package com.example.activityexample

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.example.activityexample.databinding.FirstLayoutBinding
import org.koin.android.ext.android.inject

class MainActivity : AppCompatActivity() {

    companion object {
        private const val KEY = "Value"
    }

    private lateinit var binding: FirstLayoutBinding
    private val viewModel: ActivityViewModel by inject()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = FirstLayoutBinding.inflate(layoutInflater)
        setContentView(binding.root)
        readValue()
        setupOnClick()
    }

    private fun setupOnClick() {
        binding.nextActivity.setOnClickListener {
            val result = ++viewModel.value
            viewModel.saveSet(KEY, mutableSetOf(result.toString()))
            readValue()
        }
    }

    private fun readValue() {
        val value = viewModel.readSetValue(KEY)
        value?.forEach {
            println("preference value $it")
        }
    }
}

ActivityViewModel.kt

package com.example.activityexample

import android.app.Application
import android.content.Context
import androidx.lifecycle.AndroidViewModel

class ActivityViewModel(app: Application) : AndroidViewModel(app) {

    var value = 0
    private val appLifeSharedPreferences by lazy {
        app.getSharedPreferences("vivek_pref", Context.MODE_PRIVATE)
    }

    fun saveSet(
        prefsStorageKey: String,
        setToStore: MutableSet<String>
    ) {
        val valueInSet = readSetValue(prefsStorageKey)
        valueInSet?.addAll(setToStore)
        appLifeSharedPreferences
            .edit()
            .putStringSet(prefsStorageKey, valueInSet ?: setToStore)
            .apply()
    }

    fun readSetValue(prefsStorageKey: String): MutableSet<String>? {
        val prefs = appLifeSharedPreferences
        return if (prefs.contains(prefsStorageKey)) {
            prefs.getStringSet(prefsStorageKey, null)
        } else {
            null
        }
    }
}

请看我的视频link。在我的视频中,您可以看到我点击了 3 次我的点击按钮,并且在控制台中它清楚地打印了值。但是,如果我检查偏好存储的位置,它会显示单组数据。在我重新启动我的应用程序后,甚至我的数据也没有存储价值。它正在删除先前的值。

vivek_pref.xml

<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
    <set name="Value">
        <string>1</string>
    </set>
</map>

引擎盖下的 SharedPreferences 在 getStringSet 中重用了 returns 的 MutableSet。这就是文档警告您的原因:

Note that you must not modify the set instance returned by this call. The consistency of the stored data is not guaranteed if you do, nor is your ability to modify the instance at all.

你应该立即复制返回的集,使用read-only集更简单。我还会避免不必要的可空性,因为这只会让您的代码更加冗长且可读性降低。

class ActivityViewModel(app: Application) : AndroidViewModel(app) {

    var value = 0
    private val appLifeSharedPreferences by lazy {
        app.getSharedPreferences("vivek_pref", Context.MODE_PRIVATE)
    }

    fun saveSet(
        prefsStorageKey: String,
        setToStore: Set<String>
    ) {
        val valueInSet = readSetValue(prefsStorageKey)
        appLifeSharedPreferences
            .edit()
            .putStringSet(prefsStorageKey, valueInSet + setToStore)
            .apply()
    }

    fun readSetValue(prefsStorageKey: String): Set<String> {
        return appLifeSharedPreferences.getStringSet(prefsStorageKey, null)
            ?.toSet() // create a copy for safety's sake
            .orEmpty() // avoid unnecessary nullability
    }
}

至于他们这样设计的原因,他们可能试图为您需要做的就是立即同步地迭代返回的集合然后忘记它的情况提供优化。