保存对象数组至SharedPreferences后,读取仅获最后一个对象的问题排查
问题分析与解决方案
老兄,你遇到的问题根源其实非常明显——每次添加新的历史项时,你都把整个lightHistories数组清空了!这就导致不管你点击多少次,数组里永远只有最后一次添加的那个对象,存到SharedPreferences里自然也只能读到最后一个。
除此之外,读取数据时的循环逻辑也有问题,你遍历的是原来的lightHistories的长度,而不是从SharedPreferences读到的新数组长度,这会导致读取不到正确的数据。
下面是分步修复方案:
1. 修复添加项时的清空问题
在addItemToHistory方法里,删掉lightHistories.clear()这一行。这行代码会在每次点击时清空所有历史记录,只保留当前点击的项。修改后的方法如下:
public void addItemToHistory(int position) { String title = mLightsArray.get(position).getLampTitle(); String desc = mLightsArray.get(position).getLampDesc(); String imageURL = mLightsArray.get(position).getLampImageUrl(); lightsHistory = new LightsHistory(imageURL, title, desc); // 移除这行致命代码:lightHistories.clear(); lightHistories.add(lightsHistory); // 优化UI更新逻辑(可选,更简洁) int displayIndex = i % 3; Glide.with(getContext()) .load(lightsHistory.getmLightsIMG()) .override(150) .into(historyItemsPH.get(displayIndex)); i = displayIndex + 1; saveToSharedPrefs(lightHistories); }
2. 修复读取数据时的循环逻辑
在readFromSharedPrefs方法里,你需要遍历从SharedPreferences读取到的arrayList,而不是原来的lightHistories。同时,要把读取到的数据赋值给lightHistories,这样后续添加新项时才能基于已有历史继续累加:
public void readFromSharedPrefs() { SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(getActivity()); Gson gson = new Gson(); String json = sharedPrefs.getString(TAG, ""); Type type = new TypeToken<List<LightsHistory>>() {}.getType(); ArrayList<LightsHistory> arrayList = gson.fromJson(json, type); if (arrayList != null) { // 清空原有数据,避免重复加载 lightHistories.clear(); lightHistories.addAll(arrayList); // 遍历读取到的数组,打印日志 for (LightsHistory item : arrayList) { Log.d(TAG, "readFromSharedPrefs: " + item.getmLightsTitle() + "\n" + item.getmLightsDesc() + "\n" + item.getmLightsIMG()); } // 同时更新UI,显示所有历史项(假设最多显示3个) for (int j = 0; j < Math.min(lightHistories.size(), 3); j++) { Glide.with(getContext()) .load(lightHistories.get(j).getmLightsIMG()) .override(150) .into(historyItemsPH.get(j)); } i = lightHistories.size() % 3; // 记录当前显示位置 } }
3. 初始化与退出保存优化
- 在Fragment的
onViewCreated方法中调用readFromSharedPrefs(),确保打开Fragment时就能加载之前保存的历史记录:@Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); // 初始化视图组件... readFromSharedPrefs(); } - 保留你原本计划的
onDestroyView保存逻辑,确保Fragment销毁时能保存最新的历史数据:@Override public void onDestroyView() { super.onDestroyView(); saveToSharedPrefs(lightHistories); }
额外注意事项
- 确保
LightsHistory类的字段名与Gson序列化的要求一致,或者使用@SerializedName注解指定字段名,避免序列化/反序列化失败。 - 如果你的历史记录可能很多,可以考虑限制数组的最大长度(比如最多保存10条),避免SharedPreferences存储过大的数据。
内容的提问来源于stack exchange,提问作者Michael
相关产品推荐
相关产品推荐

