Tengo un cliente de Android que se comunica con el servidor a través de extremos REST-ful y JSON. Debido a esto, tengo la necesidad de recuperar la respuesta completa del servidor antes de convertirla en Hash. Tengo este código en lugar de hacer eso (que se encuentra en algún lugar de Internet):Android: Convertir flujo a cadena sin quedarse sin memoria
private static String convertStreamToString(InputStream is) {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return sb.toString();
}
El código funciona en su mayor parte, sin embargo estoy viendo informes de accidentes en el campo de los clientes con una excepción OutOfMemory en el línea:
while ((line = reader.readLine()) != null) {
el seguimiento de pila completo es:
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:200)
at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
at java.lang.Thread.run(Thread.java:1102)
Caused by: java.lang.OutOfMemoryError
at java.lang.String.(String.java:468)
at java.lang.AbstractStringBuilder.toString(AbstractStringBuilder.java:659)
at java.lang.StringBuilder.toString(StringBuilder.java:664)
at java.io.BufferedReader.readLine(BufferedReader.java:448)
at com.appspot.myapp.util.RestClient.convertStreamToString(RestClient.java:303)
at com.appspot.myapp.util.RestClient.executeRequest(RestClient.java:281)
at com.appspot.myapp.util.RestClient.Execute(RestClient.java:178)
at com.appspot.myapp.$LoadProfilesTask.doInBackground(GridViewActivity.java:1178)
at com.appspot.myapp.$LoadProfilesTask.doInBackground(GridViewActivity.java:1)
at android.os.AsyncTask$2.call(AsyncTask.java:185)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
... 4 more
Mi pregunta: ¿hay alguna manera de resolver este problema, aparte de enviar fragmentos más pequeños de datos desde el servidor?
Gracias!
no veo la necesidad de tener toda la respuesta en la memoria a la vez. ¿Podrías profundizar en eso? –
Estaba usando la clase org.json.JSONObject, que viene de serie con Android, y carece de una API de transmisión. Pero, resulta que Jackson tiene una API de transmisión que investigaré ... – esilver