2

我正在使用DefaultHTTPClient发出一些 HTTP GET 请求。我想强制将所有 HTTP 响应缓存一周。在浏览了文档和一些 SO 答案之后,我已经这样做了:

HttpResponseCache我通过onCreate我的主要活动的方法安装了一个。

    try {
        File httpCacheDir = new File(getApplicationContext().getCacheDir(), "http");
        long httpCacheSize = 10 * 1024 * 1024; // 10 MiB
        HttpResponseCache.install(httpCacheDir, httpCacheSize);
    } catch (IOException e) {
        Log.i("dd", "HTTP response cache installation failed:" + e);
    }

我为我的 HTTP 客户端添加了一个自定义HttpResponseInterceptor,但我仍然没有得到缓存命中。这是我的响应拦截器,它解压缩 GZIPped 内容、剥离缓存标头并添加自定义标头:

class Decompressor implements HttpResponseInterceptor {

    public void process(HttpResponse hreResponse, HttpContext hctContext) throws HttpException, IOException {

        hreResponse.removeHeaders("Expires");
        hreResponse.removeHeaders("Pragma");
        hreResponse.removeHeaders("Cache-Control");
        hreResponse.addHeader("Cache-Control", "max-age=604800");

        HttpEntity entity = hreResponse.getEntity();

        if (entity != null) {
            Header ceheader = entity.getContentEncoding();
            if (ceheader != null) {
                HeaderElement[] codecs = ceheader.getElements();
                for (int i = 0; i < codecs.length; i++) {
                    if (codecs[i].getName().equalsIgnoreCase("gzip")) {
                        hreResponse.setEntity(new HttpEntityWrapper(entity) {
                            @Override
                            public InputStream getContent() throws IOException, IllegalStateException {
                                return new GZIPInputStream(wrappedEntity.getContent());
                            }

                            @Override
                            public long getContentLength() {
                                return -1;
                            }
                        });
                        return;
                    }
                }
            }
        }
    }

}

以下是我提出请求的方式:

String strResponse = null;

HttpGet htpGet = new HttpGet(strUrl);
htpGet.addHeader("Accept-Encoding", "gzip");
htpGet.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:15.0) Gecko/20100101 Firefox/15.0.1");
DefaultHttpClient dhcClient = new DefaultHttpClient();
dhcClient.addResponseInterceptor(new Decompressor(), 0);
HttpResponse resResponse = dhcClient.execute(htpGet);
Log.d("helpers.network", String.format("Cache hit count: %d", HttpResponseCache.getInstalled().getHitCount()));

strResponse = EntityUtils.toString(resResponse.getEntity());

return strResponse;

我似乎无法确定我做错了什么。你们有谁知道吗?

4

2 回答 2

0

不确定这是否回答了您的问题,但您是否考虑过使用 Android 自己的缓存目录简单地添加客户端缓存,而不是依赖 HTTP 服务器解释您的缓存控制标头?

我们在点火中所做的只是将服务器响应作为字节流写入磁盘,从而完全控制缓存(和过期缓存)。

这里有一个示例应用程序,但它需要您使用库的 HTTP API(不过,它只是 HttpClient 的一个瘦包装器。)或者只是看看缓存是如何工作的,然后从那里开始。

于 2012-09-28T13:08:47.050 回答
0

我失败了。根据 Android 文档,它特别提到了HttpResponseCache缓存对文件系统的 HTTP 和 HTTPS 响应,以便它们可以被重用,从而节省时间和带宽。这个类支持 HttpURLConnection 和 HttpsURLConnection;没有平台为 DefaultHttpClient 或 AndroidHttpClient 提供缓存。”

所以就这样了。

现在 Apache 的 HTTP 客户端有一个CachingHttpClient新版本的 HTTP 客户端已经通过这个项目移植到了 Android 上。当然,我可以使用这个。

我不想使用 Apache HTTP 客户端库的 hackish 版本,所以一个想法是从 HTTP 客户端蚕食与缓存相关的位并重新整理我自己的,但它的工作量太大了。

我什至考虑过按照建议转到推荐的HttpURLConnection课程,但我遇到了其他问题。该类似乎没有好的 cookie 持久性实现。

无论如何,我跳过了所有内容。我正在通过缓存减少加载时间,为什么不更进一步,因为我使用 jSoup 从页面中抓取记录并创建ArrayList一个自定义结构,我不妨ArrayList通过Serializable在我的结构体。现在我不必等待页面请求,也不必等待 jSoup 解析缓慢。赢。

于 2012-10-02T07:14:44.297 回答