OutOfMemoryError cuando se utiliza Gson para analizar una gran respuesta JSON
URL url = new URL("http://pubapi.cryptsy.com/api.php?method=orderdatav2"); CryptsyCurrencyPairsReturn response = gson.fromJson(new InputStreamReader(url.openStream()), CryptsyCurrencyPairsReturn.class);
Esto resulta en una excepción OutOfMemoryException para algunos de mis usuarios en dispositivos Android más antiguos. ¿Cómo puedo analizar esta gran respuesta sin quedarme sin memoria?
- ¿Cómo entender que muestra LeakCanary?
- ¿Por qué se trata de una pérdida de memoria
- Uso de la memoria de imagen de fondo Android
- Error de memoria de mapa de bits - Android
- Cómo liberar memoria en android para evitar fugas de memoria
- Prueba de memoria de Android
- Mensaje de registro en Android: / dev / pmem: Unmapping buffer base
- ¿Cómo puedo comprobar el uso de memoria de un objeto en java
- eliminar vistas que no son visibles en gridView
- Android no libera Bitmap de la memoria
- Cómo evitar createBitmap () bloqueo en android
- Fuera de la memoria de excepción + análisis de volcado de archivos hprof
- Cómo corregir este error: java.lang.OutOfMemoryError
Analizar grandes datos en un solo paso es siempre difícil y problemático. Sin embargo Gson viene con algunas características agradables para apoyar eso también.
Debe buscar com.google.gson.stream.JsonReader
para realizar el análisis de json mediante secuencias. Esto le permitirá analizar los datos en un orden incremental mientras está siendo descargado y los dispositivos de repuesto de errores OutOfMemory.
Para más información, lea esto .
Desde mi experiencia, necesitas transmitir los datos de JSON.
Y sí se puede utilizar google GSON para transmitir datos JSON esto es un ejemplo de cómo hacerlo:
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); }
readItemsArray función:
// read items array 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 Modelo Clase:
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; } }
antes de usar la API de streaming de google GSON también obtuve un error de OOM porque los datos de JSON que tengo son datos muy grandes (muchas imágenes y sonidos en la codificación Base64) pero con GSON streaming puedo superar ese error porque lee los datos por token no de repente. Y para Jackson JSON biblioteca creo que también tiene streaming API y cómo usarlo casi igual con mi implementación con google GSON. Espero que mi respuesta pueda ayudarte y si tienes otra pregunta sobre mi respuesta, siéntete libre de preguntar en el comentario 🙂
Yo recomendaría consultar JsonReader (API 11+), o las otras opciones como se recomienda aquí .