Android Kotlin:如何在SharedPreferences中存储与读取JSONArray
需要在SharedPreferences中存储并读取val response = JSONArray(it),使用Gson过程中遇到多种问题,具体尝试及问题如下:
尝试1:
prefs.edit().putString("amz", response.toString()).apply() val jsonPref = prefs.getString("amz", "") val jArr: JsonArray = Gson().fromJson(jsonPref, JsonArray::class.java) val title = jArr.getJSONObject(0).getString("title")
- 错误:
getJSONObject提示unresolved reference - 对比:直接调用
response.getJSONObject(0).getString("title")可正常运行,response.toString()为转义格式,jArr未转义
尝试2:
prefs.edit().putString("amz", response.toString()).apply() val jsonPref = prefs.getString("amz", "") val jArr: JsonArray = JsonParser.parseString(jsonPref).asJsonArray val title = jArr.getJSONObject(0).getString("title")
- 问题与尝试1完全一致
尝试3:
prefs.edit().putString("amz", Gson().toJson(response)).apply() val jsonPref = prefs.getString("amz", "") val jArr: JsonArray = Gson().fromJson(jsonPref, JsonArray::class.java)
- 错误:
Expected a com.google.gson.JsonArray but was com.google.gson.JsonObject
尝试4:
prefs.edit().putString("amz", Gson().toJson(response)).apply() val jsonPref = prefs.getString("amz", "") val jArr: JSONArray = Gson().fromJson(jsonPref, JSONArray::class.java)
- 异常结果:打印
jArr得到格式异常的数组,每个元素被包裹为带nameValuePairs的字符串:
["{nameValuePairs={asin=B0015Z9KS2, title=Eierbecher mit Stil ^^ 🐔🥚🐔, picurl=\/amzimg\/B0015Z9KS2.jpg}}","{nameValuePairs={asin=B002SQG4TU, title=S**t happens... 😋😍😁, picurl=\/amzimg\/B002SQG4TU.jpg}}"]
解决方案
方案1:直接使用原生JSONArray读写
无需借助Gson,直接存储原生JSONArray的标准字符串,读取时转回原生对象:
// 存储 prefs.edit().putString("amz", response.toString()).apply() // 读取 val jsonPref = prefs.getString("amz", "[]") val jArr = JSONArray(jsonPref) val title = jArr.getJSONObject(0).getString("title")
- 原理:原生
JSONArray.toString()生成标准JSON字符串,JSONArray(jsonString)可直接解析,适配原生方法调用。
方案2:用Gson统一处理(推荐)
核心问题是混淆了Android原生org.json.JSONArray和Gson的com.google.gson.JsonArray,两者方法不兼容,需统一类型处理:
方式A:转换为Gson的JsonArray
// 存储:将原生JSONArray转为Gson JsonArray后存字符串 val gsonArray = JsonParser.parseString(response.toString()).asJsonArray prefs.edit().putString("amz", gsonArray.toString()).apply() // 读取:解析为Gson JsonArray,用Gson方法取值 val jsonPref = prefs.getString("amz", "[]") val gsonArray = Gson().fromJson(jsonPref, JsonArray::class.java) val title = gsonArray.get(0).asJsonObject.get("title").asString
- 注意:Gson的
JsonArray无getJSONObject方法,需用get(index).asJsonObject获取对象,再通过get(key).asString取值。
方式B:转换为自定义数据类(最推荐)
定义对应数据类,通过Gson直接序列化/反序列化,实现类型安全:
// 定义数据类匹配JSON结构 data class AmzItem( val asin: String, val title: String, val picurl: String ) // 存储:将原生JSONArray转为数据类列表后存字符串 val itemList = Gson().fromJson(response.toString(), Array<AmzItem>::class.java).toList() prefs.edit().putString("amz", Gson().toJson(itemList)).apply() // 读取:直接解析为数据类列表 val jsonPref = prefs.getString("amz", "[]") val itemList = Gson().fromJson(jsonPref, Array<AmzItem>::class.java).toList() val title = itemList[0].title
- 优势:代码简洁,类型安全,避免手动解析JSON的繁琐与错误。
内容的提问来源于stack exchange,提问作者Eduard Unruh
相关产品推荐
相关产品推荐

