2011-02-27 12 views
5

Actualicé mi teléfono a Gingerbread hoy (2.3.2) y encendí una aplicación que desarrollé y vi que no pudo cargar sus datos. La aplicación funciona bien en cualquier otra versión de Android que he probado de 1.6 a 2.2, pero luego una IOException en Gingerbread. ¿Alguien sabe si algo cambió en GZipInputStream o URL.openStream()?GZIPInputStream falla con IOException en Android 2.3, pero funciona bien en todas las versiones anteriores?

El código problemática es similar al siguiente:

InputStream in = null; 
GZIPInputStream zin = null; 
URL url = null; 
try { 
    url = new URL("http://www.test.com/gzipped_data.gz"); 
    in = url.openStream(); 
    zin = new GZIPInputStream(in); 
} 
catch (MalformedURLException e) { 
    return false; 
} 
catch (IOException e) { 
    return false; 
} 

en la versión 1.6 a 2.2, este código funciona bien, en el 2,3 consigo una IOException con un mensaje sobre el bloque de la magia de ser incorrectos. Asumo que algo ha cambiado con openStream que está estropeando el tipo MIME o algo así en esta información. Leí en otros lugares que openStream no es la forma más confiable de manejar las conexiones HTTP, por lo que esta podría ser una buena excusa para volver a trabajar en mi código de conexiones.

+1

Funciona bien si cambio el código para usar HttpClient y uso una solicitud HttpGet en él. Algo debe haberse roto en la función URL.openStream(). Oh, bueno, con suerte esto ayudará a salvar a alguien más en algún momento. –

Respuesta

4

Me encuentro con el mismo problema aquí. Parece que Gingerbread (2.3) cambió la forma en que se manejan las corrientes GZipped. Ver los caracteres del "bloque mágico" indica que openStream() detecta automáticamente datos GZipped y los ejecuta a través del decodificador de flujo correcto. Por supuesto, si intenta ejecutar otro decodificador GZIP en la misma transmisión, eso fallará con una IOException.

Hay varias formas de manejar esto. La primera forma es cambiar a HttpClient/HttpGet. PERO no hay garantía de que esto tampoco cambie en el futuro. Básicamente, es un truco para que vuelva a funcionar. Una solución más completa podría ser la de hacer:

InputStream in = url.openStream(); 
GZIPInputStream zin; 
try { 
    zin = (GZIPInputStream)in; 
} catch (Exception e) { 
    zin = new GZIPInputStream(in); 
} 

Para versiones anteriores de Android, un fuego de excepción al intentar el reparto y, en las versiones más recientes de Android, la conversión se realiza correctamente. Abusar de una manejador de excepciones de esta manera no es bonito, pero funciona.

Esto, por supuesto, será un problema para los datos subyacentes que son datos comprimidos o binarios que parecen ser datos comprimidos GZIP. Los desarrolladores de Android piensan que este cambio no es un error:

http://code.google.com/p/android/issues/detail?id=16227

no estoy de acuerdo. Esto es una rotura severa.

Cuestiones relacionadas