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

将MutableMap存入SharedPreferences后读取崩溃问题求助

问题分析与解决

核心问题

报错Expected BEGIN_OBJECT but was NUMBER的本质原因:当SharedPreferences中还不存在stepsRecord这个键时,你调用getString("stepsRecord", "0")会返回默认值"0",而Gson尝试把字符串"0"解析成Map对象时必然失败——因为JSON里0是数字类型,而Map对应的合法JSON格式应该是{}这样的对象结构。

解决方案

1. 修正默认值与空值判断

把读取时的默认值改为null或空字符串,解析前先判断内容是否有效:

val mapYearMonthsString: String? = sharedPreferences.getString("stepsRecord", null)
return if (!mapYearMonthsString.isNullOrEmpty()) {
    // 用TypeToken指定完整泛型类型解析
    val type = object : TypeToken<MutableMap<Int, Map<Int, Map<Int, Map<Map<String, Int>, Int>>>>>() {}.type
    Gson().fromJson(mapYearMonthsString, type)
} else {
    // 返回初始化的空Map
    HashMap<Int, Map<Int, Map<Int, Map<Map<String, Int>, Int>>>>()
}

2. 用TypeToken处理泛型解析

直接用MutableMap::class.java解析会丢失嵌套泛型的类型信息,后续强制类型转换容易引发异常。通过TypeToken可以让Gson准确识别复杂的嵌套Map结构,保证解析结果的类型正确性。

3. 可选:更换存储方式

你的Map嵌套层级极深(Int -> Map<Int, Map<Int, Map<Map<String, Int>, Int>>>),虽然用SharedPreferences能实现存储,但维护和解析成本较高。如果数据量较大或需要后续查询操作,建议改用Room数据库,它更适配结构化数据的持久化,能更好地处理层级关系与类型安全。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 13:16:58