【发布时间】:2013-05-21 13:05:19
【问题描述】:
在解析大型 json 数据时在 android 中使用 JsonReader 类时出现异常。
例外:
java.lang.IllegalStateException: Expected a name but was STRING
json数据有效,但是我查不出这个异常的原因!
非常感谢!
我的代码:
public void readJsonStream(InputStream in) throws IOException {
JsonReader reader = new JsonReader(new InputStreamReader(in));
reader.setLenient(true);
try {
readJsonObject(reader);
} catch (Exception e) {
System.out.println(e);
} finally {
reader.close();
}
}
// Read Json From JsonReader Class
public void readJsonObject(JsonReader reader) throws IOException {
reader.beginObject();
while (reader.hasNext()) {
String name = reader.nextName();
System.out.println(name.equals("result"));
if (name.equals("result")) {
reader.beginObject();
while (reader.hasNext()) {
String josnParser = reader.nextName();
if (josnParser.equals(optionmaster)) { // Optionmaster
reader.beginArray();
while (reader.hasNext()) {
readJsonArray(reader);
}
reader.endArray();
} else {
reader.skipValue();
}
}
reader.endObject();
} else {
reader.skipValue();
}
}
reader.endObject();
}
public void readJsonArray(JsonReader reader) throws IOException {
reader.beginObject();
while (reader.hasNext()) {
String name = reader.nextName();
System.out.println(name); // Here is My Exception ....
if (name.equals("om_id")&& reader.peek() != JsonToken.NULL) {
String om_id = reader.nextString();
}
else if (name.equals("om_multiselect")&& reader.peek() != JsonToken.NULL) {
String om_multiselect = reader.nextString();
}
else if (name.equals("omlang_name")&& reader.peek() != JsonToken.NULL) {
String omlang_name = reader.nextString();
}
else if (name.equals("om_createdDate")&& reader.peek() != JsonToken.NULL) {
String om_createdDate = reader.nextString();
}
else
{
reader.skipValue();
}
}
reader.endObject();
}
这是 JSON 数据:
{
"result": {
"options": [
{
"opt_id": "8",
"opt_om_id": "3",
"optlang_name": "test1"
},
{
"opt_id": "9",
"opt_om_id": "3",
"optlang_name": "test"
}
],
"optionmaster": [
{
"om_id": "2",
"om_multiselect": "N",
"omlang_name": "Style",
"om_createdDate": "2012-08-25 01:37:57"
},
{
"om_id": "3",
"om_multiselect": "Y",
"omlang_name": "TEst",
"om_createdDate": "2012-08-25 01:37:57"
}
]
}
}
这是我的示例代码,请查看,我成功解析了选项数组,我无法解析 optionmaster 尝试解析“om_id”时出现的错误
Logcat:
05-21 17:39:54.833: W/System.err(1116): java.lang.IllegalStateException: Expected a name but was STRING
05-21 17:39:54.833: W/System.err(1116): at android.util.JsonReader.nextName(JsonReader.java:390)
05-21 17:39:54.843: W/System.err(1116): at com.test.JsonParser.readJsonArray(JsonParser.java:174)
05-21 17:39:54.843: W/System.err(1116): at com.test.JsonParser.readJsonObject(JsonParser.java:135)
05-21 17:39:54.843: W/System.err(1116): at com.test.JsonParser.readJsonStream(JsonParser.java:49)
05-21 17:39:54.843: W/System.err(1116): at com.test.ItemListActivity$ApiSyncController.doInBackground(ItemListActivity.java:149)
05-21 17:39:54.853: W/System.err(1116): at com.test.ItemListActivity$ApiSyncController.doInBackground(ItemListActivity.java:1)
05-21 17:39:54.853: W/System.err(1116): at android.os.AsyncTask$2.call(AsyncTask.java:287)
05-21 17:39:54.853: W/System.err(1116): at java.util.concurrent.FutureTask.run(FutureTask.java:234)
05-21 17:39:54.863: W/System.err(1116): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
05-21 17:39:54.863: W/System.err(1116): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
05-21 17:39:54.863: W/System.err(1116): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
05-21 17:39:54.863: W/System.err(1116): at java.lang.Thread.run(Thread.java:856)........
【问题讨论】:
-
请贴出堆栈跟踪和相关代码sn-p。
-
java.lang.IllegalStateException: 应为名称,但为 STRING 05-21 18:48:57.502: W/System.err(3631): at android.util.JsonReader.nextName(JsonReader.java :390) 05-21 18:48:57.502: W/System.err(3631): 在 com.tapendium.JsonParser.readJsonArray(JsonParser.java:299) 05-21 18:48:57.502: W/System.err (3631): 在 com.tapendium.JsonParser.readJsonObject(JsonParser.java:144) 05-21 18:48:57.512: W/System.err(3631): 在
-
这些是堆栈跟踪日志,我使用 josnlint.com 验证了 josn,它是有效的,异常我知道密钥为空,但是当我调试时,我可以在阅读器对象中看到正确的 json ,
-
你能发布你的代码吗?在调用 nextName() 之前是否调用了 beginArray() 和 beginObject()?如果您对特定值不感兴趣,您是否调用了 skipValue()?没有看到你的代码很难猜到......
-
在您的 readJsonArray() 中,您还必须读取值!读取名称后调用 nextString()、nextDouble()、.. 或 skipValue()。否则,您的代码将在循环的第二次迭代中调用 nextName() 并失败,因为堆栈仍然包含第一次迭代的值。