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,

Другие вопросы по тегам