首页 > 解决方案 > 如何序列化字符串gson的字符串和子数组(对象?)

问题描述

初学者!

在 Github 上有测验应用程序的完整代码,该代码从(数据先前存储在)中加载了List四个参数:jsonxml

  1. 问题
  2. 图片
  3. radioGroup(子列表)中提供的四个可能的答案
  4. 正确答案
   [{
        "question": "Who is the 'Modern Love' rock star singer?",
        "imageUrl": "https://postimg.cc/2VL1Y1jd",
        "answerOptions": [{
            "1": "Jaimie Hendrix",
            "2": "David Bowie",
            "3": "Jim Morrison",
            "4": "Elvis Presley"
        }],
        "correctAnswer": "David Bowie"
    }]

我收到错误

java.lang.IllegalStateException:应为字符串,但在第 1 行第 118 列路径 $[0].answerOptions[0] 处为 BEGIN_OBJECT

那是因为我已将所有请求的数据类型声明为字符串,而显然我有一个混合类型的数组(一个对象和一个数组):

@Override
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
     if (response.isSuccessful()) {
          String string = response.body().string();
          Gson gson = new Gson();
          Type type = new TypeToken<List<Quiz>>(){}.getType();
          List<Quiz> list = gson.fromJson(string, type);

          // Save to database
          for (int i = 0; i < list.size(); i++) {
              Quiz quiz = list.get(i);
              quiz.save();
          }
...

我可以在桥接类中实现解决方案

class Quiz extends LitePalSupport {
    String question;
    String imageUrl;
    String [] answerOptions;
    String correctAnswer;

    Quiz(String question, String imageUrl, String [] answerOptions, String correctAnswer) {
        this.question = question;
        this.imageUrl = imageUrl;
        this.answerOptions = answerOptions;
        this.correctAnswer = correctAnswer;
    }
}

但这意味着我将向期望的适配器视图持有者发送一个子类String []

...
quizHolder.createRadioButtons(quiz.answerOptions);
...
void createRadioButtons(String[] answerOptions) {
    if (radioGroup.getChildAt(0) != null)
        radioGroup.removeAllViews();
    for (String s : answerOptions) {
        radioGroup.addView(createRadioButtonAnswerAndSetOnClickListener(s));
    }
}
...

有没有办法在不创建子类的情况下从 json 获取子列表?


编辑:

在@andy-turner 推荐的更改之后,我收到了错误:

org.litepal.exceptions.LitePalSupportException:尝试在空对象引用上调用虚拟方法“java.lang.Class[] java.lang.reflect.Constructor.getParameterTypes()”

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.celebrityquiz, PID: 6493
    org.litepal.exceptions.LitePalSupportException: Attempt to invoke virtual method 'java.lang.Class[] java.lang.reflect.Constructor.getParameterTypes()' on a null object reference
        at org.litepal.crud.DataHandler.query(DataHandler.java:154)
        at org.litepal.crud.QueryHandler.onFindAll(QueryHandler.java:123)
        at org.litepal.Operator.findAll(Operator.java:1117)
        at org.litepal.Operator.findAll(Operator.java:1082)
        at org.litepal.LitePal.findAll(LitePal.java:798)
        at com.example.celebrityquiz.MainActivity$1$2.run(MainActivity.java:115)
        at android.os.Handler.handleCallback(Handler.java:751)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:154)
        at android.app.ActivityThread.main(ActivityThread.java:6077)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)
...

当我尝试从数据库中获取数据时可能会调用:

List<Quiz> list = LitePal.findAll(Quiz.class);

而且该answerOptions列也没有出现

在此处输入图像描述

标签: javaobjectgson

解决方案


answerOptions应为String[],但您已将其指定为Object[](因为{}):

    "answerOptions": [{
        ...
    }],

使其成为字符串数组:

    "answerOptions": [
        "Jaimie Hendrix",
        "David Bowie",
        "Jim Morrison",
        "Elvis Presley"
    ],

PS - “吉米”,而不是“杰米”。


推荐阅读