2016-11-15 9 views
0

J'ai le code suivant:Jsonreader Erreur d'analyse

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

Il retourne le JSON suivant:

{ 
    "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": "[email protected]", 
     "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 
    } 
} 

Je parse le lecteur de la façon suivante:

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 obtenez l'erreur suivante:

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) 
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) 

Est-il possible d'analyser le Jsonreader différemment? Je veux les valeurs de champs comme birthday, end_term, bioguide_id, etc. Le parser manuellement comme ceci est difficile et je dois faire beaucoup d'autres appels d'API qui peuvent renvoyer des résultats différents de Json alors je dois passer du temps à l'analyser. J'ai essayé d'utiliser BufferedReader, mais cela provoque une erreur de mémoire insuffisante en cas de retour de fichier JSON volumineux.

+1

double possible de [Comment analyser JSON dans Android] (http://stackoverflow.com/questions/9605913/how-to-parse-json-in-android) –

+0

Ce n'est pas un doublon je pense parce que je ne peux pas utiliser BufferedReader beca utilisez-le pour OutOfMemory pour les gros retours JSON. – Anirban

+0

Ce n'est pas la pièce importante. Vous obtenez une chaîne, vous le mettez dans un 'new JSONObject', et vous commencez à analyser –

Répondre

2

Regardez attentivement votre code:

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

Quand « anniversaire » est le nom de la propriété, vous ne consommez pas la valeur, ainsi de suite du passage suivant à travers la boucle, vous appelez nextName() mais l'analyseur est toujours sur la valeur.

Utilisez ce lieu:

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

également que les commentaires ont souligné, vous devez avoir un endObject() correspondant pour chaque beginObject() et un endArray() correspondant pour chaque beginArray(). Je suppose que vous effectuez des appels réseau en utilisant AsyncTask

+0

Merci ... le message est marqué comme un doublon ... comment puis-je le faire enlever ?? – Anirban

+0

que le code a/ne compile pas et b/aurait des résultats surprenants s'il didi. – njzk2

+0

@ njzk2 Hmmm .... Bon point. Ces accolades dang! Va corriger –

0
C'est fastidieux et vous pouvez faire beaucoup de très mauvaises choses ( https://www.youtube.com/watch?v=jtlRNNhane0) de cette façon. Vous êtes beaucoup, beaucoup mieux d'utiliser des bibliothèques comme OkHttp (Utilisé par HttpUrlConnection sous le capot), Retrofit, Volley, Picasso, etc .. Non seulement réduit la complexité, mais est également beaucoup plus rapide que AsyncTask s dans certaines situations ( http://instructure.github.io/blog/2013/12/09/volley-vs-retrofit/). L'utilisation d'une bibliothèque comme Retrofit signifie que vous pouvez utiliser un FactoryConverter pour convertir automatiquement JSON en POJO (pas besoin de le lire manuellement). Tout ce que vous devez faire est de créer un POJO pour correspondre à votre JSON ( http://www.jsonschema2pojo.org/) et de définir l'interface API et un rappel et Retrofit s'occupera du reste.

Pour utiliser Retrofit avec convertisseur Gson ajouter les dépendances suivantes à votre fichier de construction gradle:

compile 'com.squareup.retrofit2:retrofit:2.1.0' 
compile 'com.squareup.retrofit2:converter-gson:2.0.2' 

Voici un exemple simple d'une classe de service en utilisant un convertisseur Gson convertir en POJO:

Première créer une classe d'interface pour définir vos appels API:

public interface GitHubService { 
    @GET("users/{user}/repos") 
    Call<List<Repo>> listRepos(@Path("user") String user); 
} 

Ensuite, créez une instance de l'aide (mise en œuvre pris en charge par Retrofit): 0.123.

Retrofit retrofit = new Retrofit.Builder() 
    .baseUrl("https://api.github.com") 
    .addConverterFactory(GsonConverterFactory.create()) 
    .build(); 

GitHubService service = retrofit.create(GitHubService.class); 

Ensuite, vous faire un appel à l'aide:

Call<List<Repo>> repos = service.listRepos("octocat"); 

Vous obtenez un POJO de votre définition déjà converti de JSON.

Jetez un oeil les ressources suivantes pour obtenir un meilleur coup de lui:

https://square.github.io/retrofit/

https://github.com/square/retrofit/

OMI la meilleure documentation de Rénovation: https://futurestud.io/tutorials/retrofit-getting-started-and-android-client

+0

c'est sympa, mais ça ne répond pas à la question. – njzk2

+0

"L'analyse manuelle de ce type est difficile et je dois faire beaucoup d'autres appels d'API qui peuvent renvoyer des résultats JSON différents, mais je dois passer du temps à l'analyser, j'ai essayé d'utiliser BufferedReader grand retour de fichier Json. " Je répondais à ça .. –