You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android:重启应用后SharedPreferences的getStringSet()仅返回[]或[1]

Hey,我碰到过类似的SharedPreferences问题,帮你梳理下可能的原因和解决办法~

首先得明确:SharedPreferences本身不支持直接存储集合,我们一般是把集合序列化为JSON字符串来持久化,再反序列化为集合读取。你的问题大概率出在读取逻辑的默认值处理、内存集合与持久化数据不同步,或者保存时没做持久化提交这几个点上。

1. 先检查你的存储/读取逻辑是否正确实现

给你一个标准的实现示例(用Gson做序列化,如果你用其他库逻辑类似):

正确的存储方法

// 获取SharedPreferences实例,MODE_PRIVATE保证只有你的应用能访问
val sharedPref = context.getSharedPreferences("FavoritesPrefs", Context.MODE_PRIVATE)
// 要保存的String集合
val favoriteIds = listOf("id_001", "id_002", "id_003")
// 把集合序列化为JSON字符串
val jsonString = Gson().toJson(favoriteIds)
// 一定要调用apply()或commit()完成持久化!
sharedPref.edit().putString("saved_favorite_ids", jsonString).apply()

正确的读取方法

val sharedPref = context.getSharedPreferences("FavoritesPrefs", Context.MODE_PRIVATE)
// 读取时默认值设为null,而不是直接返回空数组的JSON!
val savedJson = sharedPref.getString("saved_favorite_ids", null)
val favoriteIds = if (savedJson != null) {
    // 反序列化为String集合
    Gson().fromJson(savedJson, object : TypeToken<List<String>>() {}.type)
} else {
    // 第一次启动时返回空集合,这里也可以选择把空集合写入SP(可选)
    emptyList<String>()
}

这里的关键是:读取时不要把默认值设为"[]"(空数组的JSON),否则当SP里本来有保存的内容时,不会触发正确的反序列化逻辑。

2. 别搞混内存集合和持久化集合

很多人会在ViewModel或Activity里维护一个内存中的MutableList来操作收藏项,但容易犯一个错:重启应用后没有从SP读取数据填充这个内存集合,直接用了空的内存集合,就误以为SP里的内容丢了。

举个正确的ViewModel示例:

class FavoritesViewModel : ViewModel() {
    private val sharedPref = ApplicationProvider.getApplicationContext<Context>()
        .getSharedPreferences("FavoritesPrefs", Context.MODE_PRIVATE)
    // 内存中的收藏集合
    val favoriteIds = mutableListOf<String>()

    init {
        // 初始化时必须先从SP加载数据填充内存集合!
        val savedJson = sharedPref.getString("saved_favorite_ids", null)
        savedJson?.let {
            val savedList = Gson().fromJson(it, object : TypeToken<List<String>>() {}.type)
            favoriteIds.addAll(savedList)
        }
    }

    // 保存时把内存集合同步到SP
    fun saveFavorites() {
        val jsonString = Gson().toJson(favoriteIds)
        sharedPref.edit().putString("saved_favorite_ids", jsonString).apply()
    }
}

这样重启后,内存集合会自动从SP加载之前保存的内容,不会变成空数组,除非SP里确实没有任何数据。

3. 确认保存时执行了持久化提交

一定要记住:调用edit().putString(...)之后,必须调用apply()或者commit()才能把修改写入磁盘。如果漏了这一步,修改只会停留在内存里,重启后就会丢失。

❌ 错误示例(没提交):

sharedPref.edit().putString("saved_favorite_ids", jsonString)

✅ 正确示例:

// 推荐用apply(),异步提交不阻塞主线程
sharedPref.edit().putString("saved_favorite_ids", jsonString).apply()
// 或者用commit(),同步提交(会阻塞线程,不建议在主线程使用)
sharedPref.edit().putString("saved_favorite_ids", jsonString).commit()

4. 排查是否有意外清除SP的操作

检查你的代码里有没有调用sharedPref.edit().clear()或者sharedPref.edit().remove("saved_favorite_ids")的逻辑,比如在用户登出、应用退出的场景下,是不是误删了这个key的值。如果有,确认它只在真正需要清除的时候执行,而不是每次启动都触发。

按上面的步骤排查一遍,应该就能解决你的问题啦~

内容的提问来源于stack exchange,提问作者pajus_cz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 07:05:39