2011-01-30 16 views
5

El siguiente código funciona bien en Android 1.5-2.2.1 pero no está en 2.3 y superior.java.io.IOException: BufferedInputStream está cerrado en Android 2.3

BufferedReader rd; 
rd = new BufferedReader(new InputStreamReader(connection.getInputStream())); 

StringBuffer sb = new StringBuffer(); 
String line; 
while ((line = rd.readLine()) != null){ 
    sb.append(line); 
} 
rd.close(); 

El stracktrace:

01-30 08:21:42.668: WARN/System.err(594): java.io.IOException: BufferedInputStream is closed 
01-30 08:21:42.668: WARN/System.err(594):  at java.io.BufferedInputStream.streamClosed(BufferedInputStream.java:116) 
01-30 08:21:42.728: WARN/System.err(594):  at java.io.BufferedInputStream.read(BufferedInputStream.java:274) 
01-30 08:21:42.728: WARN/System.err(594):  at org.apache.harmony.luni.internal.net.www.protocol.http.UnknownLengthHttpInputStream.read(UnknownLengthHttpInputStream.java:40) 
01-30 08:21:42.758: WARN/System.err(594):  at java.io.InputStreamReader.read(InputStreamReader.java:255) 
01-30 08:21:42.758: WARN/System.err(594):  at java.io.BufferedReader.fillBuf(BufferedReader.java:128) 
01-30 08:21:42.758: WARN/System.err(594):  at java.io.BufferedReader.readLine(BufferedReader.java:357) 

¿Es esto un problema? ¿Ha cambiado algo en 2.3?

+0

¿Qué enunciado de su código arroja la IOException? – TheCottonSilk

+0

Esto: while ((line = rd.readLine())! = Null) – sergi

Respuesta

9

Me di cuenta de esto también. Una cosa que puede hacer es comprobar el estado de la BufferedReader al final de su bucle:

while((line = rd.readLine()) != null){ 
    sb.append(line); 
    if (!rd.ready()) { 
     break; 
    } 
} 
rd.close(); 

Sin embargo, listo() no garantiza que su flujo se encuentra al final. Solo verifica si la transmisión está bloqueada o cerrada. Ver BufferedReader.ready() on developer.android.com

Creo que este es un error introducido en el sistema operativo Android 2.3 y superior. Contribuya a la base de errores en el sitio oficial de Android para alentar a Google a solucionar este problema. Desafortunadamente, ya hay muchos dispositivos que ya se han enviado con las versiones del sistema operativo 2.3 a 2.3.3.

Su situación es que probablemente haya tocado el final del archivo en una sola lectura y la secuencia se cerrará automáticamente. Creo que es un error introducido en Android 2.3 y superior.

La publicación de glassonion funcionará, pero esa solución funcionará muy lentamente en largos flujos de datos.

Dado que las aplicaciones móviles pueden perder conectividad a Internet en cualquier momento, el InputStream del que está leyendo simplemente puede bloquearse y esperar más datos.

Un enfoque más adecuado puede ser abrir un socket en un nuevo hilo, leer los datos y esperar con un tiempo de espera para protegerse contra cualquier lentitud en su conexión.

The following article explica el manejo de las conexiones estancadas bastante bien. Leer el resumen debería ser suficiente para convencerte.

Todas las buenas aplicaciones de red incluirán detección y manejo del tiempo de espera. Si está escribiendo un cliente y necesita detectar un servidor obsoleto o escribir un servidor y necesita evitar conexiones bloqueadas, el manejo del tiempo de espera es una parte crítica del manejo de errores.

+1

Gracias por la ayuda. Ya había ingresado esto como un error. http://code.google.com/p/android/issues/detail?id=14562 – sergi

+0

@sergi ¡De nada! Glassonion y yo trabajamos juntos y protagonizamos el error. Si recibe algún comentario de Google, infórmenos. (y viceversa) – bumbobway

+2

Para todos los demás, haga clic en el enlace de la estrella en la parte inferior de esta página http://code.google.com/p/android/issues/detail?id=14562 para ayudar a Google a priorizar esta corrección de error . – bumbobway

2

solución alternativa está por debajo.

InputStreamReader sr; 
sr = new InputStreamReader(connection.getInputStream(), "UTF-8"); 
StringBuilder builder = new StringBuilder(); 
for (int bt = 0; (bt = sr.read()) != -1;) { 
    builder.append((char)bt); 
} 
sr.close(); 
Cuestiones relacionadas