Beginner!
I have quiz app full code on Github that loads a List
with four arguments from json
(data was previously stored in xml
):
- question
- image
- four possible answers presented in a
radioGroup
(sub-List) - correct answer
[{
"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"
}]
I'm getting the error
java.lang.IllegalStateException: Expected a string but was BEGIN_OBJECT at line 1 column 118 path $[0].answerOptions[0]
and that's because I have declared all datatyped requested as strings while clearly I have an array of mixed types (an object and an array):
@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();
}
...
I could implement the solution here in the bridge class:
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;
}
}
but that means I'll be sending a SubClass to the adapter view holder which is expecting String []
...
quizHolder.createRadioButtons(quiz.answerOptions);
...
void createRadioButtons(String[] answerOptions) {
if (radioGroup.getChildAt(0) != null)
radioGroup.removeAllViews();
for (String s : answerOptions) {
radioGroup.addView(createRadioButtonAnswerAndSetOnClickListener(s));
}
}
...
Is there a way I could get the sub-list from json without creating a subclass?
Edit:
After the recommended change by @andy-turner I'm getting the error:
org.litepal.exceptions.LitePalSupportException: Attempt to invoke virtual method 'java.lang.Class[] java.lang.reflect.Constructor.getParameterTypes()' on a null object reference
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)
...
probably invoked when I try to get the data from the databse:
List<Quiz> list = LitePal.findAll(Quiz.class);
And the answerOptions
column isn't showing up either