GZIPInputStream не работает с IOException в Android 2.3, но отлично работает во всех предыдущих выпусках? - PullRequest
5 голосов
/ 27 февраля 2011

Я обновил свой телефон до Gingerbread сегодня (2.3.2) и запустил приложение, которое я разработал, и увидел, что оно не может загрузить свои данные. Приложение отлично работает на всех других версиях Android, которые я тестировал с 1.6 до 2.2, но затем IOException в Gingerbread. Кто-нибудь знает, изменилось ли что-то в 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 Ответ

4 голосов
/ 21 июня 2011

Я сталкиваюсь с той же проблемой здесь. Похоже, что 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

Я не согласен. Это серьезная поломка.

...