【问题标题】:gson.toJson declares multiple JSON fields named XXgson.toJson 声明了多个名为 XX 的 JSON 字段
【发布时间】:2019-01-07 12:20:31
【问题描述】:

我有一个 A 类型的自定义对象和一个包含 B 类型的自定义对象的 ArrayList,我想用 gson 将它们存储在我的共享首选项中。对象 A 可以正常工作,但是当我尝试存储对象 B 的列表甚至是 B 的一个实例时,会出现以下错误消息:

2019-01-07 13:05:21.610 28295-28295/com.example.aev.quizzle E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.aev.quizzle, PID: 28295
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.aev.quizzle/com.example.aev.quizzle.activities.MapsActivity}: java.lang.IllegalArgumentException: class android.content.res.ColorStateList declares multiple JSON fields named mChangingConfigurations
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3194)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3302)
    at android.app.ActivityThread.-wrap12(Unknown Source:0)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1891)
    at android.os.Handler.dispatchMessage(Handler.java:108)
    at android.os.Looper.loop(Looper.java:166)
    at android.app.ActivityThread.main(ActivityThread.java:7425)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921)
 Caused by: java.lang.IllegalArgumentException: class android.content.res.ColorStateList declares multiple JSON fields named mChangingConfigurations
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:172)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:102)
    at com.google.gson.Gson.getAdapter(Gson.java:458)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:117)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:166)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:102)
    at com.google.gson.Gson.getAdapter(Gson.java:458)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:117)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:166)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:102)
    at com.google.gson.Gson.getAdapter(Gson.java:458)
    at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:56)
    at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:97)
    at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:61)
    at com.google.gson.Gson.toJson(Gson.java:704)
    at com.google.gson.Gson.toJson(Gson.java:683)
    at com.google.gson.Gson.toJson(Gson.java:638)
    at com.google.gson.Gson.toJson(Gson.java:618)
    at com.example.aev.quizzle.activities.MapsActivity.generateThemes(MapsActivity.java:592)
    at com.example.aev.quizzle.activities.MapsActivity.onCreate(MapsActivity.java:164)
    at android.app.Activity.performCreate(Activity.java:7383)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1218)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3147)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3302) 
    at android.app.ActivityThread.-wrap12(Unknown Source:0) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1891) 
    at android.os.Handler.dispatchMessage(Handler.java:108) 
    at android.os.Looper.loop(Looper.java:166) 
    at android.app.ActivityThread.main(ActivityThread.java:7425) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921) 

我这样存储数组列表:

themes = new ArrayList<>();
themes.add(new Theme(0, this));
themes.add(new Theme(1, this));
themes.add(new Theme(2, this));

String jsonTheme = gson.toJson(themes);
prefsEditor.putString("themes", jsonTheme);
prefsEditor.commit();

我的班级主题是这样的:

public class Theme implements Parcelable {
    public ImageView icon;
    public int themeID;
    //public Question[] questions = new Question[14];
    public List<Question> questions = new ArrayList<>();
    boolean unlocked;
    Context context;

我已经看到了类似的问题,在超类和应该存储的对象中存在相同变量名的问题,但在我的情况下,我没有在我的 Theme 类中扩展另一个类。 错误指向说

的行
String jsonTheme = gson.toJson(themes);

我是在错误地对待 gson 对象还是遗漏了什么?

【问题讨论】:

  • 您是否尝试过使用toJson(Object)toJson(Object, Type) 变体?
  • 当使用任何 JSON 序列化库时,您只想序列化您的数据,否则 Gson(在这种情况下)将尝试将未设计为转换的内部对象转换为 JSON。我尝试将要转换为 JSON 的对象与包含不相关成员的对象分开,或者将我不想序列化的对象标记为 transient。我认为 Gson 正在序列化 ImageView 或 Context 并得到它,如果没有其余代码,就无法判断。
  • @KaranMer 是的,它没有任何区别
  • @AlexC 非常感谢!将瞬态放在上下文和 ImageView 前面解决了这个问题。

标签: java android gson


【解决方案1】:

使用@Transient 是解决此序列化问题的一种方法。正如您在反序列化后可能还注意到的那样,您需要将这些 ImageViewContext 设置为每个反序列化的 Theme,这可能是一个小问题。

您还可以考虑将要持久化的数据与视图和上下文等瞬态数据分开。只查看了一小部分代码,您的结构可能类似于:

类似:

public class Theme {
    public ImageView icon;
    Context context;
    ThemeData themeData

    public Theme(Context contect, ImageView icon, ThemeData themeData) {
        this.context = context;
        this.icon = icon;
        themeData = themeData;
    }

    public void doSomethingWithThemeDataAndViewAndContext() {
        // whatever you need to do in Theme
    }
}

其中ThemeData 包含所有非瞬态字段,然后您将坚持到SharedPreferences

public class ThemeData {
    public int themeID;
    //public Question[] questions = new Question[14];
    public List<Question> questions = new ArrayList<>();
    boolean unlocked;
}

另请注意:我认为如果您使用 GSON 序列化主题并将其保存为 SharedPreferences 中的 JSON 字符串,则无需实现 Parcelable,因此我将其删除。

【讨论】:

    猜你喜欢
    • 2014-09-09
    • 1970-01-01
    • 2016-01-25
    • 2021-02-13
    • 1970-01-01
    • 2017-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多