HttpResponseCache не работает в Android Lollipop
Я успешно использую в своем приложении HttpResponseCache, но когда мой телефон обновился до Lollipop, я понял, что HttpResponseCache теперь никогда не получает "удар", всегда выполняю сетевой запрос. Я подтвердил, что в версиях Android pre Lollipop все еще работает хорошо. Может быть, я что-то не так сделал и с новыми изменениями в Android он появился.
У кого-нибудь есть идеи?
Мой код:
Класс приложения, onCreate...
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
try {
File httpCacheDir = new File(getApplicationContext().getCacheDir()
, "http");
long httpCacheSize = 10 * 1024 * 1024;
HttpResponseCache.install(httpCacheDir, httpCacheSize);
} catch (IOException e) {
Log.i(TAG, "HTTP response cache installation failed:" + e);
}
} else {
try {
File httpCacheDir = new File(getCacheDir(), "http");
long httpCacheSize = 10 * 1024 * 1024;
Class.forName("android.net.http.HttpResponseCache")
.getMethod("install", File.class, long.class)
.invoke(null, httpCacheDir, httpCacheSize);
} catch (Exception e) {
Log.i(TAG, "HTTP response cache installation failed:" +
}
}
Функция для управления запросом
public static InputStream fetchInputStream(String strURL, boolean forceRefresh)
throws IOException {
HttpURLConnection mHttpConn = null;
InputStream inputStream = null;
URL url = new URL(strURL);
HttpResponseCache cache;
try {
mHttpConn = (HttpURLConnection) url.openConnection();
if (forceRefresh) {
mHttpConn.addRequestProperty("Cache-Control", "no-cache");
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
cache = HttpResponseCache.getInstalled();
if (cache != null) {
Log.i("TEST CACHE", "TEST PETICION: Req count: "
+ cache.getRequestCount() + ", hit count "
+ cache.getHitCount() + ", netWork count "
+ cache.getNetworkCount() + " size = "
+ cache.size() + " <-----------------");
}
}
mHttpConn.setUseCaches(true);
mHttpConn.setDefaultUseCaches(true);
mHttpConn.setRequestMethod("GET");
mHttpConn.setConnectTimeout(30000);
mHttpConn.setReadTimeout(30000);
mHttpConn.connect();
if (mHttpConn.getResponseCode() == HttpURLConnection.HTTP_OK) {
inputStream = mHttpConn.getInputStream();
}
} catch (IOException ex) {
Log.e("NetworkConnectionManager InputStream", "Exception opening ["
+ strURL + "] ->", ex);
mHttpConn.disconnect();
throw ex;
}
return inputStream;
}
После каждого запроса
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
HttpResponseCache cache = HttpResponseCache.getInstalled();
if (cache != null) {
cache.flush();
}
}
Пример заголовка запроса:
- Cache-Control → max-age = 300
- Соединение → поддерживать
- Content-Encoding → gzip
- Content-Type → application / json; кодировка = UTF-8
- Дата → Ср, 08 Апр. 2015 12:37:35 GMT
- Истекает → Ср, 08 Апр 2015 12:42:35 GMT
- Последнее изменение → Ср, 08 апреля 2015 12:37:35 GMT
- Сервер → nginx
- Передача-Кодировка → чанкинг
- Варь → Принять-Кодировка
- X-Cached → MISS
2 ответа
После нескольких дней этой проблемы я столкнулся с этой проблемой. Это исправлено снова в Зефир.
Это ошибка в lollipop, когда заголовок Vary - > Accept-Encoding нарушает кеш, потому что Accept-Encoding заполняется по умолчанию, но не записывается.
Вот ссылка на вопрос:
https://code.google.com/p/android/issues/detail?id=162475
Исправление заключается в явной установке Accept-Encoding:
Accept-Encoding -> gzip
или же
Accept-Encoding -> личность
На стороне чтения вы должны добавить это к чтению входного потока:
String encoding = urlConnection.getHeaderField("Content-Encoding");
boolean gzipped = encoding!=null && encoding.toLowerCase().contains("gzip");
Inputstream inputStream;
if(gzipped)
inputStream = new GZIPInputStream(urlConnection.getInputStream());
else
inputstream = urlConnection.getInputStream();
У меня была похожая проблема. Я ожидал, что изображения будут кэшированы, но это не так.
Проблема оказалась в том, что я не закрывал InputStream
после того, как это читается в растровое изображение.
Ваш fetchInputStream
возвращает InputStream, полученный от http-соединения, убедитесь, что вы правильно его закрыли.
Http-кеш Android не сохранит ресурс, пока вы не закроете соединение InputStream
,