【问题标题】:GZIPInputStream fails with IOException in Android 2.3, but works fine in all previous releases?GZIPInputStream 在 Android 2.3 中因 IOException 而失败,但在所有以前的版本中都可以正常工作吗?
【发布时间】:2011-02-27 02:20:37
【问题描述】:

我今天将手机更新为 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 连接的最可靠方法,因此这可能是重新编写连接代码的好借口。

【问题讨论】:

  • 如果我将代码更改为使用 HttpClient 并在其上使用 HttpGet 请求,则效果很好。 URL.openStream() 函数中一定有问题。哦,好吧,希望这能帮助其他人节省一些时间。

标签: android gzip gzipinputstream


【解决方案1】:

我在这里遇到了同样的问题。看起来 Gingerbread (2.3) 改变了 GZipped 流的处理方式。查看“魔术块”字符表明 openStream() 自动检测 GZipped 数据并通过正确的流解码器运行它。当然,如果您尝试在同一个流上运行另一个 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

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

【讨论】:

    猜你喜欢
    • 2022-07-06
    • 2012-07-26
    • 1970-01-01
    • 1970-01-01
    • 2021-01-10
    • 1970-01-01
    • 1970-01-01
    • 2020-08-25
    • 2018-05-29
    相关资源
    最近更新 更多