首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何强制缓存所有HTTP响应?

如何强制缓存所有HTTP响应?
EN

Stack Overflow用户
提问于 2012-09-28 20:20:38
回答 2查看 1.3K关注 0票数 2

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

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

代码语言:javascript
复制
    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);
    }

我为我的超文本传输协议客户端添加了一个定制的HttpResponseInterceptor,但是我仍然没有得到缓存命中。这是我的响应拦截器,它解压GZIPped内容,剥离缓存头,并添加一个自定义的:

代码语言:javascript
复制
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;
                    }
                }
            }
        }
    }

}

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

代码语言:javascript
复制
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;

我似乎找不到我做错了什么。你们有人知道吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-10-02 15:14:44

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

所以这已经过时了。

现在Apache的HTTP client有了一个CachingHttpClient,这个新版本的HTTP client已经通过this project被移植回Android。当然,我可以用这个。

我不想使用Apache HTTP客户端库的黑客版本,所以有一个想法是从HTTP客户机取走与缓存相关的部分,并重新卷起我自己的部分,但这太麻烦了。

我甚至考虑过按照推荐的方式转到推荐的HttpURLConnection类,但我遇到了其他问题。这个类似乎没有好的cookie持久化实现。

不管怎样,我跳过了所有的东西。我正在通过缓存减少加载时间,为什么不更进一步,因为我使用jSoup从页面中抓取记录并创建自定义结构的ArrayList,所以我还可以通过在我的结构上实现Serializable方法来序列化整个ArrayList。现在我不必等待页面请求,也不必等待jSoup解析速度变慢。赢。

票数 0
EN

Stack Overflow用户

发布于 2012-09-28 21:08:47

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

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

有一个示例应用程序here,但它要求您使用库的HTTP API (然而,它只是HttpClient的一个薄薄的包装器)。或者简单地看一下缓存是如何工作的,然后从那里开始。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12639922

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档