2016-11-15 230 views
0

我有下面的代碼:Jsonreader解析錯誤

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

它返回以下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": "[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 
    } 
} 

我分析下列方式的讀者:

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()); 
} 

我得到以下錯誤:

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) 

有沒有辦法以不同的方式解析Jsonreader?我想要像生日,end_term,bioguide_id等字段的值。像這樣手動解析它很困難,我必須做許多其他的API調用,這可能會返回不同的JSON結果,然後我不得不花時間解析它。我試圖使用BufferedReader,但是在大Json文件返回的情況下會出現Out Of Memory錯誤。小心你的代碼

+1

的可能的複製[如何解析JSON在Android](http://stackoverflow.com/questions/9605913/how-to-parse-json-in-android) –

+0

它不是重複我認爲,因爲我不能使用BufferedReader beca使用它給OutOfMemory大Json返回。 – Anirban

+0

這不是重要的一塊。你得到一個字符串,你把它放到一個'新的JSONObject'中,並且你開始解析 –

回答

2

看:

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

當「生日」是屬性名,你不消耗值,所以在下一次循環,你叫nextName()但解析器仍然在價值上。

使用這個代替:

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

此外,作爲評論所指出的那樣,你需要爲每個beginObject()和每個beginArray()匹配的endArray()匹配的endObject()

+0

謝謝...該帖子被標記爲重複...我怎麼能刪除它? – Anirban

+0

代碼a /不編譯和b /如果它didi會有令人驚訝的結果。 – njzk2

+0

@ njzk2嗯....好點。那些大括號!將修復 –

0

我假設您使用AsyncTask進行網絡通話。這很乏味,你可以用這種方式做很多非常糟糕的事情(https://www.youtube.com/watch?v=jtlRNNhane0)。你可以使用OkHttp(引擎蓋下的HttpUrlConnection),Retrofit,Volley,Picasso等庫。它不僅降低了複雜性,而且在某些情況下也比AsyncTask快得多(http://instructure.github.io/blog/2013/12/09/volley-vs-retrofit/)。

使用類似Retrofit的庫意味着您可以使用FactoryConverter將JSON自動轉換爲POJO(無需手動讀取)。所有你需要做的就是創建一個POJO來匹配你的JSON(http://www.jsonschema2pojo.org/)並定義API接口和一個回調函數,Retrofit將負責其餘的部分。

要使用改造與GSON轉換器添加以下依賴於你的gradle這個構建文件:

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

下面是一個使用GSON轉換器轉換到一個POJO服務類的一個簡單的例子:

第一創建一個接口類來定義您的API調用:

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

然後使用(由Retrofit負責的實施)創建它的一個實例:

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

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

那麼您必須先透過電話:從JSON已經轉換了您定義的POJO

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

你得到。

看看下面的資源來獲取一個更好的竅門:

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

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

IMO改造的最好的文檔:https://futurestud.io/tutorials/retrofit-getting-started-and-android-client

+0

這很好,但是這並沒有回答這個問題。 – njzk2

+0

「像這樣手動解析它很困難,我必須做很多其他的API調用,它們可能會返回不同的Json結果,然後我不得不花費時間解析它。我嘗試使用BufferedReader,但是如果出現Out of Memory錯誤大Json文件返回「。我正在回答這個問題.. –