OutOfMemoryError quando si utilizza Gson per analizzare una grande risposta JSON

URL url = new URL("http://pubapi.cryptsy.com/api.php?method=orderdatav2"); CryptsyCurrencyPairsReturn response = gson.fromJson(new InputStreamReader(url.openStream()), CryptsyCurrencyPairsReturn.class); 

Ciò provoca un OutOfMemoryException per alcuni dei miei utenti su vecchi dispositivi Android. Come posso analizzare questa grande risposta senza esaurirsi di memory?

  • android come fermare gps
  • android rendendo il layout scorrevole quando la tastiera soft apre, ma non lo sposta verso l'alto
  • Scorrimento tra attività
  • Eseguire un'operazione a lunga corsa in onDestroy
  • Può un'applicazione Android sapere quando è in esecuzione un'altra applicazione Android?
  • Scansione dei dispositivi bluetooth vicini
  • Come mettere RecyclerView all'interno di NestedScrollView?
  • Il tutorial di Google Android OpenGL insegna un'algebra lineare errata?
  • Modificare il progresso SeekBar basato sul valore EditText
  • Come faccio a produrre la posizione utilizzando gps su Android
  • Perché Android 4.0 / Ice Cream Sandwich assegna così memory di heap?
  • Come riprodurre i video da SD Card
  • 3 Solutions collect form web for “OutOfMemoryError quando si utilizza Gson per analizzare una grande risposta JSON”

    Analizzare dati di grandi size in una go è sempre difficile e fastidioso. Tuttavia Gson viene fornito con alcune belle caratteristiche per sostenere anche questo.

    Dovresti cercare com.google.gson.stream.JsonReader per eseguire l'analisi di json utilizzando i flussi. Ciò consentirà di analizzare i dati in un ordine incrementale mentre viene scaricato e di memorizzare i dispositivi dagli errori di OutOfMemory.

    Per ulteriori informazioni, leggere questo .

    Dalla mia esperienza, devi eseguire i flussi dei dati JSON.
    E sì, puoi utilizzare google GSON per il stream di dati JSON, questo è un esempio di come farlo:

     APIModel result = new APIModel(); try { HttpResponse response; HttpClient myClient = new DefaultHttpClient(); HttpPost myConnection = new HttpPost(APIParam.API_001_PRESENT( serial_id, api_key)); try { response = myClient.execute(myConnection); Reader streamReader = new InputStreamReader(response .getEntity().getContent()); JsonReader reader = new JsonReader(streamReader); reader.beginObject(); while (reader.hasNext()) { String name = reader.nextName(); if (name.equals("result")) { if (reader.nextString() == "NG") { result.setResult(Util.API_001_RESULT_NG); break; } } else if (name.equals("items")) { result = readItemsArray(reader); } else { reader.skipValue(); // avoid some unhandle events } } reader.endObject(); reader.close(); } catch (Exception e) { e.printStackTrace(); result.setResult(Util.API_001_RESULT_NG); } } catch (Exception e) { e.printStackTrace(); result.setResult(Util.API_001_RESULT_NG); } 

    function readItemsArray:

     // read items arrays private APIModel readItemsArray(JsonReader reader) throws IOException { APIModel result = new APIModel(); String item_name, file_name, data; result.setResult(Util.API_001_RESULT_OK); reader.beginArray(); while (reader.hasNext()) { item_name = ""; file_name = ""; data = ""; reader.beginObject(); while (reader.hasNext()) { String name = reader.nextName(); if (name.equals("name")) { item_name = reader.nextString(); } else if (name.equals("file")) { file_name = reader.nextString(); } else if (name.equals("data")) { data = reader.nextString(); } else { reader.skipValue(); } } reader.endObject(); result.populateModel("null", item_name, file_name, data); } reader.endArray(); return result; } 

    API Classe Modello:

     public class APIModel { private int result; private String error_title; private String error_message; private ArrayList<String> type; private ArrayList<String> item_name; private ArrayList<String> file_name; private ArrayList<String> data; public APIModel() { result = -1; error_title = ""; error_message = ""; setType(new ArrayList<String>()); setItem_name(new ArrayList<String>()); setFile_name(new ArrayList<String>()); setData(new ArrayList<String>()); } public void populateModel(String type, String item_name, String file_name, String data) { this.type.add(type); this.item_name.add(item_name); this.file_name.add(file_name); this.data.add(data); } public int getResult() { return result; } public void setResult(int result) { this.result = result; } public String getError_title() { return error_title; } public void setError_title(String error_title) { this.error_title = error_title; } public String getError_message() { return error_message; } public void setError_message(String error_message) { this.error_message = error_message; } public ArrayList<String> getType() { return type; } public void setType(ArrayList<String> type) { this.type = type; } public ArrayList<String> getItem_name() { return item_name; } public void setItem_name(ArrayList<String> item_name) { this.item_name = item_name; } public ArrayList<String> getFile_name() { return file_name; } public void setFile_name(ArrayList<String> file_name) { this.file_name = file_name; } public ArrayList<String> getData() { return data; } public void setData(ArrayList<String> data) { this.data = data; } } 

    prima di utilizzare l'API di streaming da google GSON ho anche ottenuto l'errore OOM perché i dati JSON che ho ottenuto sono dati molto grandi (molte immagini e suoni in codifica Base64) ma con lo streaming GSON posso superare questo errore perché legge i dati per token non tutto in una volta. E per la libreria di Jackson JSON penso che abbia anche API streaming e come utilizzarlo quasi lo stesso con la mia implementazione con google GSON. Spero che la mia risposta possa aiutarti e se avete un'altra domanda sulla mia risposta, non esitate a chiedere nel commento 🙂

    Consiglierei di guardare a JsonReader (API 11+) o alle altre opzioni come raccomandato qui .

    L'Android è un fan Android di Google, tutto su telefoni Android, Android Wear, Android Dev e applicazioni Android Games e così via.