2012-09-28 27 views
2

我正在使用DefaultHTTPClient来进行一些HTTP GET请求。我想强制缓存一周的所有HTTP响应。通过文档和一些SO回答后,我已经这样做了:如何强制缓存我所有的HTTP响应?

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

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我的HTTP客户端,但我仍然没有得到缓存命中。下面是解压gzip压缩的内容我的反应拦截,剥离缓存头,并增加了一个自定义的:

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; 

我似乎无法找出什么我做错了。你们中的任何人都知道吗?

+0

Idk什么'HttpResonseCache'可以做,但你可以创建一个文件缓存封装HttpClient手动或者你可以尝试使用'HttpUrlConnection'它有缓存,因为ICS http://android-developers.blogspot.de/2011/09/androids -http-clients.html – zapl

+0

有一个叫做缓存控制的标题信息,我不确定它可以帮忙或没有帮助,但是如果你仍然想知道该怎么做,请对此进行一些研究。 –

+0

@Dhruvenkumar Shah,如果你看看我的代码,你会看到我手动设置'Cache-Control'头。 –

回答

0

我对此失败了。根据Android文档,它特别说明了关于HttpResponseCache-“缓存对文件系统的HTTP和HTTPS响应,以便它们可以重复使用,节省时间和带宽。该类支持HttpURLConnection和HttpsURLConnection;没有平台提供的用于DefaultHttpClient的缓存或AndroidHttpClient“。

这样就出来了。

现在,Apache的HTTP客户端有一个CachingHttpClient,这个新版本的HTTP客户端已通过this project返回到Android。当然,我可以用这个。

我不想使用hackish版本的Apache HTTP客户端库,所以一个想法是从HTTP客户端抢占与缓存相关的位,并让我自己的资源重新使用,但这是太多的工作。

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

无论如何,我忽略了一切,尽管如此。我通过缓存减少了加载时间,为什么没有更进一步,因为我使用jSoup从页面刮记录并创建一个定制结构的ArrayList,我不妨通过实现10序列化整个ArrayList方法在我的结构上。现在我不必等待页面请求,也不必等待jSoup解析缓慢。赢得。

+0

不知道这是否也有帮助,但是这里有一些关于实现缓存的信息,并非针对Android,而是希望有所帮助。 https://developer.att.com/developer/forward.jsp?passedItemId=9700192 –

0

不知道这是否回答你的问题,而是依赖于HTTP服务器来解释你的缓存控制头,你有没有想过只需使用Android自己的缓存目录添加客户端缓存?

我们在点火没有什么是简单地写服务器响应到磁盘字节流,因此具有在高速缓存的完全控制(和到期高速缓存)。

有一个示例应用程序here,但它需要你使用图书馆的HTTP API(然而,它仅仅是HttpClient的一个简单包装)。或者简单地看看缓存如何工作并从那里开始。

+0

如果你看看我的代码,你会发现我并不依赖服务器来解释我的头文件。我正在处理响应对象。我剥去了所有的头文件,并添加了一个自定义的“Cache-Control”头文件。 –

+1

好吧,我明白了。这对我来说似乎是一场疯狂的黑客攻击。而且,你继续在相同的响应拦截器中使用响应,那么为什么这会被缓存在任何地方? – Matthias

+0

你有一点。我不能删除我的'HttpResponseInterceptor',否则我将无法解压缩GZIPped内容。你还有其他建议吗?我想坚持'HTTPClient'而不是切换到'HTTPURLConnection'。谢谢。 –