我正在玩JsonReader
这是Android中的流式JSON解析器,我遇到了一个问题,即解析器不会遍历json数组中的所有项目,它只会返回第一个项目
这是我用来解析的代码:
private ArrayList<Result> readResultsArray(JsonReader reader) throws IOException {
ArrayList<Result> results = new ArrayList<Result>();
reader.beginObject();
while (reader.hasNext()) {
String name = reader.nextName();
if (name.equals("results")){
reader.beginArray();
while (reader.hasNext()) {
results.add(readResult(reader));
}
reader.endArray();
} else {
reader.skipValue();
}
}
reader.endObject();
return results;
}
我确信方法readResult(reader)
会解析并返回数组中的第一个对象而没有任何问题。
但是读者似乎只是“忽略”了数组中的第二个对象。
以下是readResult(reader)
方法:
private Result readResult(JsonReader reader) throws IOException {
String from_user = null,
from_user_id_str = null,
from_user_name = null,
text = null;
Geo geo = null;
URL profile_image_url = null;
reader.beginObject();
while (reader.hasNext()) {
String name = reader.nextName();
if (name.equals("from_user")){
from_user = reader.nextString();
Log.i(TAG, from_user);
} else if (name.equals("from_user_id_str")) {
from_user_id_str = reader.nextString();
Log.i(TAG, from_user_id_str);
} else if (name.equals("from_user_name")) {
from_user_name = reader.nextString();
Log.i(TAG, from_user_name);
} else if (name.equals("geo")) {
reader.beginObject();
while(reader.hasNext()) {
// String s = reader.nextName();
if (name.equals("coordinates")) {
reader.beginArray();
double latitude = 0;
double longitude = 0;
while (reader.hasNext()) {
latitude = reader.nextDouble();
longitude = reader.nextDouble();
Log.i(TAG, latitude + ", " + longitude);
geo = new Geo(latitude, longitude);
}
reader.endArray();
} else {
reader.skipValue();
}
}
reader.endObject();
} else if (name.equals("profile_image_url")) {
profile_image_url = new URL(reader.nextString());
} else if (name.equals("text")) {
text = reader.nextString();
Log.i(TAG, text);
} else {
reader.skipValue();
}
}
reader.endObject();
return new Result(from_user, from_user_id_str, from_user_name, text, geo, profile_image_url);
}
}
这是我试图解析的JSON:
(这是Twitter搜索响应,原始回复如下所示,Link)
{
"completed_in": 0.067,
"max_id": 320160565840457730,
"max_id_str": "320160565840457730",
"page": 1,
"query": "%E5%90%83",
"refresh_url": "?since_id=320160565840457730&q=%E5%90%83&geocode=51.483372%2C-3.190826%2C200mi",
"results": [
{
"created_at": "Fri, 05 Apr 2013 13:06:41 +0000",
"from_user": "missmanchu",
"from_user_id": 359296258,
"from_user_id_str": "359296258",
"from_user_name": "miss manchu ",
"geo": null,
"location": "London, United Kingdom",
"id": 320160565840457730,
"id_str": "320160565840457730",
"iso_language_code": "ja",
"metadata": {
"result_type": "recent"
},
"profile_image_url": "http://a0.twimg.com/profile_images/3470783234/6ae4049d90a052c7a9c7f86ec804e523_normal.jpeg",
"profile_image_url_https": "https://si0.twimg.com/profile_images/3470783234/6ae4049d90a052c7a9c7f86ec804e523_normal.jpeg",
"source": "<a href="http://twitter.com/download/iphone">Twitter for iPhone</a>",
"text": "RT @lougirlie: Delish Taiwanese-style bao by @missmanchu for lunch. 好吃! http://t.co/clRznskvqe"
},
{
"created_at": "Fri, 05 Apr 2013 11:45:09 +0000",
"from_user": "lougirlie",
"from_user_id": 154974289,
"from_user_id_str": "154974289",
"from_user_name": "Louise Chow",
"geo": {
"coordinates": [
51.5216788595,
-0.1420583511
],
"type": "Point"
},
"id": 320140044142772224,
"id_str": "320140044142772224",
"iso_language_code": "ja",
"metadata": {
"result_type": "recent"
},
"place": {
"full_name": "Westminster",
"id": "548c2b8e3921a85a",
"type": "CITY"
},
"profile_image_url": "http://a0.twimg.com/profile_images/1750994903/photo_3__4__normal.JPG",
"profile_image_url_https": "https://si0.twimg.com/profile_images/1750994903/photo_3__4__normal.JPG",
"source": "<a href="http://twitter.com">Twitter for iPhone</a>",
"text": "Delish Taiwanese-style bao by @missmanchu for lunch. 好吃! http://t.co/clRznskvqe"
},
{
"created_at": "Fri, 05 Apr 2013 10:09:25 +0000",
"from_user": "geleikai",
"from_user_id": 351512769,
"from_user_id_str": "351512769",
"from_user_name": "geleikai",
"geo": null,
"location": "53.762824,-2.707418",
"id": 320115951339200512,
"id_str": "320115951339200512",
"iso_language_code": "zh",
"metadata": {
"result_type": "recent"
},
"profile_image_url": "http://a0.twimg.com/profile_images/3110335584/545b94d39e1628d747428c73a8052bf8_normal.jpeg",
"profile_image_url_https": "https://si0.twimg.com/profile_images/3110335584/545b94d39e1628d747428c73a8052bf8_normal.jpeg",
"source": "<a href="http://www.wechatapp.com">WeChat App</a>",
"text": "吃过午饭,前往阿姆斯特丹 http://t.co/LbQ0Jh7Mfp"
},
{
"created_at": "Thu, 04 Apr 2013 10:15:05 +0000",
"from_user": "hpfly",
"from_user_id": 60939059,
"from_user_id_str": "60939059",
"from_user_name": "0C哈根达斯",
"geo": null,
"location": "53.805042,-1.544011",
"id": 319754991692824576,
"id_str": "319754991692824576",
"iso_language_code": "zh",
"metadata": {
"result_type": "recent"
},
"profile_image_url": "http://a0.twimg.com/profile_images/3251267049/c56ca4cb888736299548e5454a9d923b_normal.jpeg",
"profile_image_url_https": "https://si0.twimg.com/profile_images/3251267049/c56ca4cb888736299548e5454a9d923b_normal.jpeg",
"source": "<a href="http://fanfou.com">fanfou2.0</a>",
"text": "现在对谈恋爱一点欲望都没有,更多的欲望是告诉我,我内心希望独享一个人的时光。现在特别希望晚睡,而且是晚上一个人吃着宵夜,看着电视。#如果生活可以这么单纯就好了##当然这也是晚睡的牵强理由#"
},
{
"created_at": "Wed, 03 Apr 2013 15:47:50 +0000",
"from_user": "cushingliu",
"from_user_id": 87816289,
"from_user_id_str": "87816289",
"from_user_name": "Cushing",
"geo": {
"coordinates": [
0.0,
0.0
],
"type": "Point"
},
"id": 319476345325359104,
"id_str": "319476345325359104",
"iso_language_code": "zh",
"metadata": {
"result_type": "recent"
},
"place": {
"full_name": "Batu Ampar",
"id": "ddc693317ed3f226",
"type": "CITY"
},
"profile_image_url": "http://a0.twimg.com/profile_images/3269471232/f89db3764b70bada908ab340a9fb9c85_normal.jpeg",
"profile_image_url_https": "https://si0.twimg.com/profile_images/3269471232/f89db3764b70bada908ab340a9fb9c85_normal.jpeg",
"source": "<a href="http://tapbots.com/tweetbot">Tweetbot for iOS</a>",
"text": "有妈妈做饭吃的感觉真好"
}
],
"results_per_page": 15,
"since_id": 0,
"since_id_str": "0"
}
我唯一感兴趣的部分是"results"
,它是一个包含两个对象的数组。
仔细观察Android Developers - JsonReader以及nice tutorial中的示例后,我发现我的与他们的基本没什么区别。
我的代码出了什么问题?为什么它不能用于json数组呢?
粘贴readResult(reader)
答案 0 :(得分:6)
您没有考虑将导致原始代码异常的空地理类型。使用peek()
检查是否为空。我修改了代码来处理这个问题并打印出两个对象。
class MyReader
{
public void readBegin(JsonReader reader)
{
try
{
reader.beginObject();
while (reader.hasNext())
{
String name = reader.nextName();
if (name.equals("results"))
{
reader.beginArray();
while (reader.hasNext())
{
read(reader);
}
reader.endArray();
}
else
{
reader.skipValue();
}
}
reader.endObject();
}
catch (Exception e)
{
e.printStackTrace();
}
}
public void read(JsonReader reader) throws Exception
{
String from_user = null, from_user_id_str = null, from_user_name = null, text = null;
URL profile_image_url = null;
reader.beginObject();
while (reader.hasNext())
{
String name = reader.nextName();
if (name.equals("from_user"))
{
from_user = reader.nextString();
System.out.println(from_user);
}
else if (name.equals("from_user_id_str"))
{
from_user_id_str = reader.nextString();
}
else if (name.equals("from_user_name"))
{
from_user_name = reader.nextString();
}
else if (name.equals("geo"))
{
if (reader.hasNext())
{
JsonToken peek = reader.peek();
if (peek == JsonToken.NULL)
{
reader.skipValue();
}
else
{
reader.beginObject();
while (reader.hasNext())
{
// String s = reader.nextName();
if (name.equals("coordinates"))
{
reader.beginArray();
double latitude = 0;
double longitude = 0;
while (reader.hasNext())
{
latitude = reader.nextDouble();
longitude = reader.nextDouble();
}
reader.endArray();
}
else
{
reader.skipValue();
}
}
reader.endObject();
}
}
}
else if (name.equals("profile_image_url"))
{
profile_image_url = new URL(reader.nextString());
}
else if (name.equals("text"))
{
text = reader.nextString();
}
else
{
reader.skipValue();
}
}
reader.endObject();
}