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

保存对象数组至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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 09:02:39