【问题标题】:Using Gson to serialize ArrayList of objects with non-primitive values?使用 Gson 序列化具有非原始值的对象的 ArrayList?
【发布时间】:2020-04-16 23:54:59
【问题描述】:

所以我有这门课

public class Place {

    ArrayList<Stop> stops;
    String name;
    Location location;

    public Place(String name, Location location){
        this.name = name;
        this.location = location;
    }

    public void addStop(Stop stop){
        this.stops.add(stop);
    }

    public Location getLocation() {
        return location;
    }

    public String toString(){
        return name+ " : " +location.toString();
    }
}

我用于 Android 项目。每个 Place 对象都有一个 Location 对象(来自 Google Play Services),应用程序有一个 ArrayList items 数组列表,用于存储用户输入数据。我正在使用 Gson 序列化该 ArrayList 并将其保存到 SharedPrefs,但是当我恢复数据时,来自 Location 对象的所有参数都会出现 null。这是我的代码:

//If user has defined places, load them from storage
mPrefs = getActivity().getPreferences(MODE_PRIVATE);
Gson gson = new Gson();
String json = mPrefs.getString("user_places", "");
Type placeListType = new TypeToken<ArrayList<Place>>(){}.getType();
if(json.length() > 0) items = gson.fromJson(json, placeListType);
else  items = new ArrayList<Place>();

...

//Saves user data for future use
SharedPreferences.Editor prefsEditor = mPrefs.edit();
Gson gson = new Gson();
String json = gson.toJson(items);
prefsEditor.putString("user_places", json);
prefsEditor.apply();

我做错了什么?如何确保正确还原原始 Location 对象?

【问题讨论】:

  • 1、2 或 1000 个地点和/或站点是否也会发生这种情况?
  • 您能否显示序列化后收到的JSON
  • 我最终改变了Place 的结构。它没有Location 对象,它只存储初始Location 对象的经度/纬度坐标,应用程序在反序列化时对其进行重构。当我测试 GSON 返回的JSON 字符串时,我注意到Location 对象中只有一个参数被序列化(Location 被记录的时间)。所以这可能是序列化而不是反序列化的问题

标签: java android serialization gson sharedpreferences


【解决方案1】:

如果我正确理解了您的问题,可能是因为您正在从 2 个不同的活动中加载和保存 Json 字符串。

SharedPreferences mPrefs = getActivity().getPreferences(MODE_PRIVATE);

getPreferences() 方法仅在您访问同一活动中的值时才有效。

如果您想将值保存到活动 A 中的 SharedPreferences 中,并稍后在活动 B 中获取它们,请尝试改用:

SharedPreferences mPrefs = getSharedPreferences("MySharedPreferences", MODE_PRIVATE);
SharedPreferences.Editor prefsEditor = mPrefs.edit();
Gson gson = new Gson();
String json = gson.toJson(items);
prefsEditor.putString("user_places", json);
prefsEditor.apply();

然后像这样访问它们:

SharedPreferences mPrefs = getActivity().getPreferences(MODE_PRIVATE);
Gson gson = new Gson();
String json = mPrefs.getString("user_places", "");

【讨论】:

  • 实际上都在同一个活动中......我使用 getActivity() 而不是 'this' 因为这是在片段中发生的。在将数据保存到sharedprefs 或从sharedprefs 中检索数据时,我并没有真正遇到问题。我的问题是,在反序列化时,嵌套在 Place 对象中的 Location 对象的参数(它本身嵌套在我正在保存的 ArrayList 中)为空。
  • @Dat8StringGuy 好吧,这很奇怪,我建议您在 logcat 中显示您的 Location 对象值,这样您就会知道您可能会将 null 作为参数传递给构造函数。也可以考虑创建一个字段 String locationJson,在构造函数中将位置转换为 json(如果之前您检查过传递给构造函数的 Location 对象不为空),是的,这听起来不太好,但我没有任何其他想法
猜你喜欢
  • 1970-01-01
  • 2019-01-17
  • 2022-01-15
  • 1970-01-01
  • 2015-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-18
相关资源
最近更新 更多