2

を使用しDefaultHTTPClientて、いくつかのHTTPGETリクエストを作成しています。1週間すべての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が、それでもキャッシュヒットが発生しません。これが、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;

自分が間違っていることを正確に特定できないようです。誰か知っていますか?

4

2 に答える 2

0

私はこれで惨めに失敗しました。Androidのドキュメントによると、具体的にはHttpResponseCache「ファイルシステムへのHTTPおよびHTTPS応答をキャッシュして、再利用できるようにし、時間と帯域幅を節約します。このクラスはHttpURLConnectionとHttpsURLConnectionをサポートします。DefaultHttpClientまたはAndroidHttpClient用のプラットフォーム提供のキャッシュはありません。 。」

だからそれは出ていた。

これで、ApacheのHTTPクライアントにがあり、この新しいバージョンのHTTPクライアントがこのプロジェクトCachingHttpClientを通じてAndroidにバックポートされました。もちろん、これを使うこともできます。

私はApacheHTTPクライアントライブラリのハックなバージョンを使用したくなかったので、1つのアイデアは、HTTPクライアントからのキャッシュ関連ビットを共食いし、自分自身を再構築することでしたが、それは大変な作業でした。

HttpURLConnection推奨されるクラスに移動することも検討しましたが、他の問題が発生しました。そのクラスには、適切なcookie-persistenceの実装がないようです。

とにかく、私はすべてをスキップしました。キャッシュによって読み込み時間を短縮しています。さらに一歩進んでみませんか。jSoupを使用してページからレコードを取得し、カスタム構造を作成していたので、メソッドを実装しArrayListて全体をシリアル化することもできます。構造。これで、ページ要求を待つ必要はありません。jSoupの解析が遅くなるのを待つ必要もありません。勝つ。ArrayListSerializable

于 2012-10-02T07:14:44.297 に答える
0

これがあなたの質問に答えるかどうかはわかりませんが、キャッシュ制御ヘッダーを解釈するHTTPサーバーに依存する代わりに、Android独自のキャッシュディレクトリを使用してクライアント側のキャッシュを追加することを考えましたか?

イグニッションで行ったことは、サーバーの応答をバイトストリームとしてディスクに書き込むだけです。これにより、キャッシュ(およびキャッシュの期限切れ)を完全に制御できます。

ここにサンプルアプリがありますが、ライブラリのHTTP APIを使用する必要があります(ただし、これはHttpClientの薄いラッパーにすぎません)。または、キャッシュがどのように機能するかを確認して、そこから移動します。

于 2012-09-28T13:08:47.050 に答える