2012-09-28 24 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'。謝謝。 –