Android将ArrayList<ModelClass>存入SharedPreference报JsonSyntaxException如何解决
问题根因
你对相同数据执行了两次Gson序列化操作,导致存入SharedPreference的内容是被双重转义的字符串,而非原本的List结构JSON:
- 存入前你已经通过
String json = gson.toJson(list);把List转为了JSON数组字符串 - 调用
saveString方法时,方法内部又执行了一次String json = gson.toJson(value);,把已经是字符串的JSON数组又做了一次序列化,最终存储的内容是被引号包裹的转义字符串,比如"[{\"id\":\"xxx\"...}]",而不是原本的[{"id":"xxx"...}]格式,所以读取时Gson会抛出「期望数组开头却拿到字符串」的异常。
修复方案
方案1:修改saveString方法,移除重复序列化逻辑
原本的saveString里重复做了序列化,直接存储传入的字符串即可:
public void saveString(Context context, String sharedPrefName, String value) { SharedPreferences mPrefs = context.getSharedPreferences("MYPREFERENCES", Context.MODE_PRIVATE); SharedPreferences.Editor prefsEditor = mPrefs.edit(); // 直接存入传入的JSON字符串,不需要再次序列化 prefsEditor.putString(sharedPrefName, value); prefsEditor.commit(); }
方案2:保留saveString现有逻辑,存入前不提前序列化
直接把List传入序列化方法,避免外部重复处理(建议同步修改方法参数类型避免逻辑混淆):
// 存入时直接传List,不需要提前转JSON SharedPreferenceUtils.getInstance().savePlayList(context,"playlistMediaData", list); // 同步修改方法参数类型更清晰 public void savePlayList(Context context, String sharedPrefName, List<PlayListModel> value) { SharedPreferences mPrefs = context.getSharedPreferences("MYPREFERENCES", Context.MODE_PRIVATE); SharedPreferences.Editor prefsEditor = mPrefs.edit(); Gson gson = new Gson(); String json = gson.toJson(value); prefsEditor.putString(sharedPrefName, json); prefsEditor.commit(); }
读取逻辑优化建议
你现有读取逻辑里默认值设为空字符串,无缓存时空字符串转List也会抛异常,建议调整默认值为null:
public ArrayList<PlayListModel> retrieveListJson(Context context, String sharedPrefName){ SharedPreferences mPrefs = context.getSharedPreferences("MYPREFERENCES", Context.MODE_PRIVATE); // 默认值设为null,避免空字符串转换异常 String serializedObject = mPrefs.getString(sharedPrefName, null); if (serializedObject != null) { Gson gson = new Gson(); Type type = new TypeToken<List<PlayListModel>>(){}.getType(); return gson.fromJson(serializedObject, type); } return new ArrayList<>(); }
内容的提问来源于stack exchange,提问作者Umair Iqbal
相关产品推荐
相关产品推荐

