【问题标题】:JsonReader Exception in Android while parsing large JSON data解析大型 JSON 数据时 Android 中的 JsonReader 异常
【发布时间】: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() 并失败,因为堆栈仍然包含第一次迭代的值。

标签: java android json


【解决方案1】:

我担心短路和 reader.peek 的检查未执行。 先做 reader.peek() 检查,然后检查你的 ifs

if (reader.peek()!=JsonToken.NULL) {
    if (name.equals("om_id")) {
        String om_id = reader.nextString();
    } else if (name.equals("om_multiselect")) {      
        String om_multiselect = reader.nextString();
    } else if (name.equals("omlang_name")) {
        String omlang_name = reader.nextString();
    } else if (name.equals("om_createdDate")) {
        String om_createdDate = reader.nextString();
    } else {
        reader.skipValue();
    }
}

祝你好运

【讨论】:

    【解决方案2】:

    使用这个

    while (jsonReader.peek() != JsonToken.END_DOCUMENT)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多