HttpResponseCache无法在Android Lollipop中运行

时间:2015-04-08 14:18:17

标签: android caching request android-5.0-lollipop httpresponsecache

我已成功使用我的应用程序HttpResponseCache,但当我的手机更新到Lollipop时,我意识到HttpResponseCache现在永远不会得到"命中",总是做网络请求。我已经确认在Android版本中,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
  • 连接→保持活力
  • 内容编码→gzip
  • Content-Type→application / json;字符集= UTF-8
  • 日期→星期三,2015年4月8日12:37:35 GMT
  • 到期→2015年4月8日星期三12:42:35 GMT
  • Last-Modified→Wed,08 Apr 2015 12:37:35 GMT
  • 服务器→nginx
  • 转移编码→分块
  • Vary→Accept-Encoding
  • X-Cached→MISS

2 个答案:

答案 0 :(得分:2)

在遇到这个问题好几天后,我遇到了这个问题。它再次固定在Marshmallow。

这是棒棒糖中的一个错误,其中Vary - &gt; Accept-Encoding标头会破坏缓存,因为默认情况下,Accept-Encoding会被填充但不会被写入。

以下是该问题的链接:

https://code.google.com/p/android/issues/detail?id=162475

修复方法是明确设置Accept-Encoding:

接受编码 - &gt; gzip的

接受编码 - &gt;身份

在阅读方面,您必须将其添加到输入流的读取中:

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();

答案 1 :(得分:1)

我有类似的问题。我期待图像被缓存,但它们不是。

结果是问题是我在读取位图后没有关闭 InputStream

您的fetchInputStream会返回从http连接获得的InputStream,请确保正确关闭它。

在关闭连接InputStream之前,android http缓存不会保存资源。