2013-04-08 3 views
2

Я играю с JsonReader, который является потоковым JSON-парсером на Android, и я встретил проблему, когда парсер не будет перебирать все элементы в json-массиве, это будет верните мне первый пункт.Android JsonReader не может перебирать 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 я попытался разобрать:

(Это щебетать поиск ответа, оригинальный ответ представлен, как показано ниже, 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": "&lt;a href=&quot;http://twitter.com/download/iphone&quot;&gt;Twitter for iPhone&lt;/a&gt;", 
     "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": "&lt;a href=&quot;http://twitter.com&quot;&gt;Twitter for iPhone&lt;/a&gt;", 
     "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": "&lt;a href=&quot;http://www.wechatapp.com&quot;&gt;WeChat App&lt;/a&gt;", 
     "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": "&lt;a href=&quot;http://fanfou.com&quot;&gt;fanfou2.0&lt;/a&gt;", 
     "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": "&lt;a href=&quot;http://tapbots.com/tweetbot&quot;&gt;Tweetbot for iOS&lt;/a&gt;", 
     "text": "有妈妈做饭吃的感觉真好" 
    } 
    ], 
    "results_per_page": 15, 
    "since_id": 0, 
    "since_id_str": "0" 
} 

Единственная часть, которая меня интересует, это "results", которая представляет собой массив из двух объектов.

После того, как вы внимательно посмотрели на пример в Android Developers - JsonReader, а также на этот nice tutorial, я обнаружил, что моя в основном не отличается от их.

Так что случилось с моим кодом? Почему он не может инициализировать массив json?

UPDATE

Pasted код readResult(reader)

+0

Я считаю, что термин, который вы хотите, это итерация, а не itinerate. – HalR

+0

Даже если вы уверены, что * "' readResult (reader) 'будет анализировать и возвращать первый объект в массиве без каких-либо проблем" *, есть ли вероятность, что вы не можете закрыть объект должным образом? То есть возможно, есть вызов 'reader.endObject()' отсутствует там? Было бы неплохо разделить код для 'readResult (reader)' тоже. –

+0

Я тоже подозреваю, что readResult слишком голоден и ел больше json, чем вы подозреваете. Это действительно похоже на самого вероятного виновника, хотя у нас нет источника. Вы другие вещи выглядят очень просто. – HalR

ответ

6

Вы не учет нулевых типов гео что приведет исключение на исходном коде. Используйте peek(), чтобы проверить значение null. Я изменил код, чтобы обработать это, и он печатает оба объекта.

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

thx mate, поэтому проблема вызвана «нулевым» объектом, с которым я не справился? – dumbfingers

+0

Да. Вы можете обработать это с помощью 'reader.peek();' –

+0

thx! Не могли бы вы подождать несколько часов, я попробую ваше решение после работы =) – dumbfingers

Смежные вопросы