GZIPInputStream在Android 2.3中因IOException失败,但在以前的所有版本中都能正常工作吗?

时间:2011-02-27 02:20:37

标签: android gzip gzipinputstream

我今天将手机更新为Gingerbread(2.3.2)并启动了我开发的应用程序并发现它无法加载其数据。该应用程序在我从1.6到2.2测试的每个其他Android版本上运行正常,但随后在Gingerbread中出现了IOException。有人知道GZipInputStream或URL.openStream()中是否有变化吗?

有问题的代码类似于以下内容:

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;
}

在1.6到2.2中,这段代码工作正常,在2.3中我得到一个IOException,其中包含有关魔术块不正确的消息。我假设openStream发生了一些变化,搞乱了MIME类型或者这个数据上的东西。我读了其他地方,openStream不是处理HTTP连接的最可靠的方法,所以这可能是重写我的连接代码的一个很好的借口。

1 个答案:

答案 0 :(得分:4)

我在这里遇到了同样的问题。看起来Gingerbread(2.3)改变了GZipped流的处理方式。查看“magic block”字符表示openStream()自动检测GZip数据并通过正确的流解码器运行它。当然,如果您尝试在同一个流上运行另一个GZIP解码器,则会因IOException而失败。

有几种方法可以解决这个问题。第一种方法是切换到HttpClient / HttpGet。但是不能保证将来也不会改变。基本上,这是一个让它再次运作的黑客。一个更完整的解决方案可能是:

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

对于旧版本的Android,在尝试演员时会触发异常,在较新版本的Android上,演员会成功。以这种方式滥用异常处理程序并不漂亮,但它可以正常工作。

当然,对于压缩的基础数据或看起来像是GZIP压缩数据的二进制数据,这将是一个问题。 Android开发人员认为此更改不是错误:

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

我不同意。这是严重的破坏。