2015-03-26 4 views
0

Каков наиболее эффективный способ разобрать ответ JSON с сервера, который возвращается как одна огромная линия? Я не хочу/должен «сопоставлять» этот JSON с некоторыми пользовательскими/бизнес-объектами, поскольку мне нужны только определенные части структуры.
В основном поиск определенного тега и его значений среди множества массивов.Лучший способ обработки огромного ответа HTTP JSON

UPDATE:

Ищу эффективный способ для разбора ответ JSON с внутреннего сервера.
Ответ отправляется как огромная одна строка. Файл настолько велик, что пытаться понять структуру с помощью json-плагина Брауэра все еще сложно, поскольку браузер «застрял».
Для моих нужд я хочу определенные бит информации и не хочу сопоставлять JSON с фактическим бизнес-объектом/классами, поскольку это будет слишком много ненужной работы. Что я в настоящее время сделать для тестирования на это (я удалил обработку исключений для ясности):

HttpClient client = new DefaultHttpClient(); 
HttpGet httpGet = new HttpGet(url); 
HttpResponse response = null; 
response = client.execute(httpGet); 
StatusLine statusLine = response.getStatusLine(); 
int statusCode = statusLine.getStatusCode(); 
StringBuilder builder = null; 
if (statusCode == 200) { 
      HttpEntity entity = response.getEntity(); 
      InputStream content = entity.getContent(); 
      builder = new StringBuilder(); 
      BufferedReader reader = new BufferedReader(new InputStreamReader(content)); 
      String line; 
      while ((line = reader.readLine()) != null) { 
        builder.append(line); 
      } 
      if (builder.length() != 0) { 
       processJSON(builder.toString()); 
      } 
      return builder.toString(); 
} 

private void processJSON(String s) { 
     JSONObject o = new JSONObject(s); 
     String url = (String) o.get("url"); 

     JSONArray array = o.getJSONArray("individualroles"); 

     for(int i = 0; i < array.length(); i++) { 
       JSONObject elem = (JSONObject) array.get(i); 
       String fullNameForDisplay = (String) elem.get("fullName"); 
       String status = (String) elem.get("status"); 
       String date = (String) elem.get("date"); 
       String fullDescription = (String) elem.get("full_description").toString(); 
       JSONArray contacts = (JSONArray) elem.get("contacts"); 
       for(int j = 0; j < contacts.length(); j ++) { 
        JSONObject contact = (JSONObject) contacts.get(j); 
        String contactName = contact.getString("contactName"); 
        String displayName = contact.getString("displayName"); 
        String realAddress = contact.getString("realAddress"); 

        Log.i(“MyApp”, “contactName = “ + contactName + “ displayName = “ + displayName + “ readAddress = “ + realAddress); 
       } 
     } 

Это буквально fluds журнала как ответ JSON т.е. String s имеет длину символов ~ 7million.
Кроме того, я вижу в журнале многих утверждений типа:

I/искусство: Фон липкая одновременно знак развертка GC освободила 389 (14kb) AllocSpace объектов, 3 объекта (851KB) Лось, 0% бесплатно, 2MB/2MB, приостановленный 30.651ms всего 77.127ms

Для тестирования это то, что я сделал то, что в я делаю осколком onCreate:

Thread thread = new Thread(new Runnable() { 
      @Override 
      public void run() { 
       Log.i(“MyApp”, (new JSONParser().get(JSON_URL_SERVER))); 
       } 
     }); 
     thread.start(); 

есть ли какие-либо проблемы, например, с памятью и GC с таким подходом? Как я могу улучшить это?

+2

Вы можете использовать Джексон и его потокового API, например – fge

+0

http://stackoverflow.com/questions/29272990/get-selected-items-data-in-listview-fetched-from-json/29273258#29273258 – Yogendra

+1

HTTP : //developer.android.com/reference/android/util/JsonReader.html http://www.androidhive.info/2014/09/android-json-parsing-using-volley/ – Yogendra

ответ

1

Вы должны использовать то, что разбирает InputStream во время чтения.

Подобно синтаксическим анализаторам SAX для XML существуют такие реализации для JSON. Есть Джексон для одного и alsp json-simple, который имеет довольно простой подход к нему, expained here.

Если я правильно понимаю ваш код, вы в основном ищете все под ключ "individualroles". Таким образом, используя этот SAX-подобный парсер, вы должны реализовать ContentFinder, как в примере KeyFinder, и который вызывается Parser, как только необходимый ключ будет достигнут во входном потоке. Теперь вы можете обрабатывать эту часть JSON, а затем можете закончить разбор/чтение всего.

Извините, но я не могу предоставить более подробное объяснение, но я не использовал эту конкретную библиотеку самостоятельно, это просто знание SAX-парсеров, сопоставленных JSON, которые я могу предоставить.

+0

'анализирует входной поток во время чтения', не могли бы вы рассказать об этой части? Я понимаю, что входной поток - это весь ответ, уже загруженный с сервера. Разве это не так? – Jim

+0

Не обязательно. Это зависит от того, как сервер отправляет данные. Однако независимо от этого вам не нужно читать все данные из входного потока и строить из него огромную строку, а затем анализировать все. Использование этого подхода ContentFinder так же быстро, как вы можете получить, и оно также не требует большой памяти (так что никаких проблем с GC), поскольку данные, которые вас не интересуют, не хранятся в памяти. – Ridcully

+0

Могу ли я использовать SAX-подход с волейболом? – Jim

0

Если вы хотите просто принять некоторые части структуры возвращаются как ответ, вы можете сделать это вручную:

try { 
    // if response is a single object: 
    JSONObject obe = new JSONObject(response); 
    int value = json.getInt("tag"); 
    // or if it is an array: 
    JSONArray obes = new JSONArray(response); 
    JSONObject obe = obes.getJSONObject(0); 
} catch (JSONException e) { 
}