我有以下代码:
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": "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
}
}我以以下方式解析读者:
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文件返回很大,就会产生内存不足的错误。
发布于 2016-11-15 19:18:19
仔细查看您的代码:
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()都需要一个匹配的endArray(),每个beginArray()需要一个匹配的endArray()。
发布于 2016-11-15 19:33:07
我想您是在使用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接口,然后进行回调,然后重新配置将处理剩下的部分。
若要在Gson转换器中使用Retrofit,请将以下依赖项添加到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);然后,您可以使用以下方法拨打电话:
Call<List<Repo>> repos = service.listRepos("octocat");您将得到已经从JSON转换的定义的POJO。
看看下面的资源,可以更好地掌握它:
https://square.github.io/retrofit/
https://github.com/square/retrofit/
国际海事组织翻新的最佳文献:https://futurestud.io/tutorials/retrofit-getting-started-and-android-client
https://stackoverflow.com/questions/40617731
复制相似问题