Anirban Anirban - 25 days ago 11
Android Question

Jsonreader parse error

I have a the following code:-

reader = new JsonReader(new InputStreamReader(con.getInputStream()));


It returns the following JSON:-

{
"results": [
{
"bioguide_id": "D000626",
"in_office": true,
"thomas_id": "02296",
"govtrack_id": "412675",
"crp_id": "N00038767",
"fec_ids": [
"H6OH08315"
],
"first_name": "Warren",
"nickname": null,
"last_name": "Davidson",
"middle_name": null,
"name_suffix": null,
"gender": "M",
"birthday": "1970-03-01",
"leadership_role": null,
"term_start": "2016-06-09",
"term_end": "2017-01-03",
"state": "OH",
"state_name": "Ohio",
"party": "R",
"title": "Rep",
"chamber": "house",
"phone": "202-225-6205",
"fax": null,
"website": null,
"office": "1011 Longworth House Office Building",
"contact_form": null,
"votesmart_id": 166760,
"district": 8,
"oc_email": null,
"ocd_id": "ocd-division/country:us/state:oh/cd:8"
},
{
"bioguide_id": "L000585",
"in_office": true,
"thomas_id": "02295",
"govtrack_id": "412674",
"crp_id": "N00037031",
"fec_ids": [
"H6IL18088"
],
"first_name": "Darin",
"nickname": null,
"last_name": "LaHood",
"middle_name": null,
"name_suffix": null,
"gender": "M",
"birthday": "1968-07-05",
"leadership_role": null,
"term_start": "2015-09-17",
"term_end": "2017-01-03",
"state": "IL",
"state_name": "Illinois",
"party": "R",
"title": "Rep",
"chamber": "house",
"phone": "202-225-6201",
"fax": null,
"website": "https://lahood.house.gov/",
"office": "2464 Rayburn House Office Building",
"contact_form": "https://lahood.house.gov/contact/email",
"votesmart_id": 128760,
"district": 18,
"oc_email": "Rep.Lahood@opencongress.org",
"twitter_id": "RepLaHood",
"youtube_id": null,
"facebook_id": "1499570210366431",
"ocd_id": "ocd-division/country:us/state:il/cd:18"
}
],
"count": 538,
"page": {
"count": 2,
"per_page": 2,
"page": 1
}
}


I parse the reader in the following way:-

try {
reader.beginObject();
while (reader.hasNext()) {
String name = reader.nextName();
if (name.equals("results")){
reader.beginArray();
while (reader.hasNext()) {
reader.beginObject();
while (reader.hasNext()) {
String id = reader.nextName();
if(id.equals("birthday"))
Log.d("id", id);
else
reader.skipValue();
}
}
}

else {
reader.skipValue();
}
}

}
catch (IOException e){
Log.w("Error",e.getMessage());
}


I get the following error:-

11-15 10:50:32.750 5095-5095/com.app.congress.congressapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.app.congress.congressapp, PID: 5095
java.lang.IllegalStateException: Expected a name but was STRING
at android.util.JsonReader.nextName(JsonReader.java:390)
at com.app.congress.congressapp.GetAllStates.onPostExecute(ByState.java:57)
at com.app.congress.congressapp.GetAllStates.onPostExecute(ByState.java:30)
at android.os.AsyncTask.finish(AsyncTask.java:636)
at android.os.AsyncTask.access$500(AsyncTask.java:177)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:653)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
11-15 10:51:47.250 5095-5095/com.app.congress.congressapp E/AndroidRuntime: Error reporting crash
android.os.DeadObjectException
at android.os.BinderProxy.transactNative(Native Method)
at android.os.BinderProxy.transact(Binder.java:496)
at android.app.ActivityManagerProxy.handleApplicationCrash(ActivityManagerNative.java:4164)
at com.android.internal.os.RuntimeInit$UncaughtHandler.uncaughtException(RuntimeInit.java:89)
at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:693)
at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:690)


Is there is way to parse the Jsonreader in a different way. I want the values of fields like birthday, end_term, bioguide_id etc. Parsing it manually like this is difficult and I have to make many other API calls which may return different Json results then again I have to spend time parsing it. I tried to use BufferedReader but that gives an error Out Of Memory in case of large Json file return. Please guide me am pretty new at this and have been stuck for a long time.

Answer

Look carefully at your code:

                        String id = reader.nextName();
                        if(id.equals("birthday"))
                            Log.d("id", id);
                        else
                            reader.skipValue();

When "birthday" is the property name, you don't consume the value, so on the next pass through the loop, you call nextName() but the parser is still on the value.

Use this instead:

                        String id = reader.nextName();
                        if(id.equals("birthday"))
                            Log.d("id", id);
                            reader.nextString(); // or reader.skipValue()
                        else
                            reader.skipValue();

Also as comments have pointed out, you need to have a matching endObject() for each beginObject() and a matching endArray() for each beginArray().