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

Kotlin中如何在SharedPreferences存储ArrayList对象及报错解决

解决SharedPreferences存储ArrayList的Gson解析崩溃问题

问题回顾

你在用Kotlin开发Android应用时,尝试通过Gson将ArrayList<ProductQuantityData>序列化后存入SharedPreferences,但初始实现的读取方法触发了JsonSyntaxException,错误提示为Expected BEGIN_OBJECT but was STRING。不过你已经通过修改读取方法解决了问题,我来帮你拆解下问题根源,再分享几个可以优化的点。

初始代码的问题所在

你最初的读取方法里,把Gson().toJson(ArrayList<ProductQuantityData>())作为getString的默认值——也就是把空ArrayList转成的JSON字符串([])当默认值。这个做法存在两个隐患:

  • 如果SharedPreferences里对应key的存储内容不是合法的JSON数组(比如之前误存了普通字符串,或者第一次初始化时出现异常),Gson去解析这个无效内容时,就会因为格式不匹配抛出崩溃。
  • 其实完全没必要用空数组的JSON当默认值,反而增加了出错的概率。

修正后代码的核心优化

你修改后的读取方法完美规避了这个问题,关键改动有两个:

  1. 把getString的默认值改成了空字符串"",而非空数组的JSON
  2. 先判断读取到的字符串是否为空,空的话直接返回空ArrayList;非空时再用Gson解析,从根源避免了解析无效内容的情况

这里再清晰贴出你的修正后代码:

private val sharedPreferences: SharedPreferences = context.getSharedPreferences(context.packageName, Context.MODE_PRIVATE)

fun getProductInArrayListWithQuantities(key: String): ArrayList<ProductQuantityData> {
    var prodQte: ArrayList<ProductQuantityData>
    val json = sharedPreferences.getString(key, "")
    prodQte = if (json!!.isEmpty()) {
        ArrayList()
    } else {
        val type = object : TypeToken<ArrayList<ProductQuantityData>>() {}.type
        Gson().fromJson<ArrayList<ProductQuantityData>>(json, type)
    }
    return prodQte
}

fun setProductInArrayListWithQuantities(dataArrayList: ArrayList<ProductQuantityData>, key: String) {
    val jsonString = Gson().toJson(dataArrayList)
    sharedPreferences.edit().putString(key, jsonString).apply()
}

额外的优化建议

为了让代码更健壮、性能更好,还可以做这两个优化:

  • 单例化Gson实例:每次解析都创建新的Gson对象会浪费资源,建议全局只创建一个:
    private val gson = Gson()
    
    之后所有序列化/反序列化操作都用这个实例。
  • 更安全的空处理:避免使用非空断言!!,用takeIf和let的组合来处理空值,更符合Kotlin的空安全规范:
    fun getProductInArrayListWithQuantities(key: String): ArrayList<ProductQuantityData> {
        val json = sharedPreferences.getString(key, "")
        return json.takeIf { it.isNotEmpty() }?.let {
            gson.fromJson(it, object : TypeToken<ArrayList<ProductQuantityData>>() {}.type)
        } ?: ArrayList()
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 09:14:41