如何将项目添加到存储在 sharedPreferences 中的列表?

How to add item to list stored in sharedPreferences?

我正在尝试使用 sharedPreferences 在本地存储中存储字符串列表 当我第一次为我的应用程序存储库 return null 午餐时,它应该如此。 当我尝试将任何新项目写入我的存储然后读取它时,功能

getSearchHistoryItems()

没有 return 任何数据。我写的函数有问题吗 新项目?

interface LocalPreferencesRepository {
    fun getSearchHistoryItems(): List<String>?
    fun addSearchHistoryItem(item: String)
}

class LocalPreferencesRepositoryImpl(
    private val sharedPreferences: SharedPreferences
) : LocalPreferencesRepository {

    override fun getSearchHistoryItems(): List<String>? {
        return Gson().fromJson(
            sharedPreferences.getString(PREF_SEARCH_HISTORY, null),
            object : TypeToken<ArrayList<String>>() {}.type
        )
    }

    override fun addSearchHistoryItem(item: String) {
        val listToSave = listOf(item).plus(getSearchHistoryItems())
        val json = Gson().toJson(listToSave)
        with(sharedPreferences.edit()) { putString(PREF_SEARCH_HISTORY, json); commit() }
    }

    companion object {
        private const val PREF_SEARCH_HISTORY = "PREF_SEARCH_HISTORY"
    }
}

编辑:

override fun getSearchHistoryItems(): List<String>? =
        try {
            Gson().fromJson(
                sharedPreferences.getString(PREF_SEARCH_HISTORY, "").orEmpty(),
                object : TypeToken<ArrayList<String>>() {}.type
            )
        } catch (e: Exception) {
            null
        }

listToSave 是一个 List<Any> 因为 List<String> + List<String>? 将使用 plus 的重载将第二个参数添加为单个元素而不是迭代它并添加它的所有项目。为什么不使 getSearchHistoryItems() return 成为不可空列表(return 和 .orEmpty())?

此外,我认为当 SharedPreference 中当前没有存储任何内容时,您有崩溃的危险。我不怎么使用 Gson,但是如果你向它传递一个无效的 Json 字符串或空值,它不会抛出异常吗?

另外,小费。有一个 KTX 扩展函数 SharedPreferences.edit 函数,可让您传递一个 lambda,您可以在其中进行编辑,而不必手动提交。使用起来更干净一点。默认情况下,它在内部使用 apply() 而不是 commit(),这是您通常应该做的。如果你真的需要保证在 returning 之前有一个写入,你应该使用协程或使用 Jetpack Datastore 而不是 SharedPreferences。

interface LocalPreferencesRepository {
    fun getSearchHistoryItems(): List<String>
    fun addSearchHistoryItem(item: String)
}

class LocalPreferencesRepositoryImpl(
    private val sharedPreferences: SharedPreferences
) : LocalPreferencesRepository {

    override fun getSearchHistoryItems(): List<String> {
        return Gson().fromJson(
            sharedPreferences.getString(PREF_SEARCH_HISTORY, ""),
            object : TypeToken<ArrayList<String>>() {}.type
        ).orEmpty()
    }

    override fun addSearchHistoryItem(item: String) {
        val listToSave = listOf(item).plus(getSearchHistoryItems())
        val json = Gson().toJson(listToSave)
        sharedPreferences.edit { putString(PREF_SEARCH_HISTORY, json) }
    }

    companion object {
        private const val PREF_SEARCH_HISTORY = "PREF_SEARCH_HISTORY"
    }
}