5

今日、携帯電話を 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 が発生します。MIME タイプまたはこのデータの何かを台無しにしている openStream で何かが変更されたと想定しています。openStream は HTTP 接続を処理する最も信頼できる方法ではないという他の場所を読んだので、これは接続コードを作り直す良い言い訳になるかもしれません。

4

1 に答える 1

4

ここで同じ問題に直面しています。Gingerbread (2.3) が GZipped ストリームの処理方法を変更したようです。「マジック ブロック」文字を見ると、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

同意しません。これは深刻な破損です。

于 2011-06-20T23:03:25.687 に答える