50
public class CustomRequest extends JsonObjectRequest {

    public CustomRequest(String url, JSONObject params,
            Listener<JSONObject> listener, ErrorListener errorListener)
            throws JSONException {
        super(Method.POST,url, params, listener,
                errorListener);
        this.setShouldCache(Boolean.TRUE);
    }
}

このコードで応答の暗黙的なキャッシュを取得するのに十分であることを期待していました。リクエストが送信されたときに想定していたので、機能するかどうかはわかりません。

  1. 最初にキャッシュにヒットし、それを onresponse に送信します

  2. 次に、結果がリモートサーバーから届くと、それをonresponseに提供します

アップデート:

キャッシュを手動で取得して JSONObject に再構築し、OnResponse 関数を介して送信する方法を考えましたが、暗黙的なキャッシュがあることを考えると効率的ではないようです。JsonObjectRequest クラスは、生の応答データではなく、キャッシュされたエントリとして JSONObject を返す必要があります。

しかし、私は間違いを犯しているかどうかを知りたいと思っています。

あいまいさは単にドキュメントの不足によるものであるため、明らかな何かが欠けている場合はお詫び申し上げます。

4

4 に答える 4

5

oleksandr_yefremov は、特に REST API に不適切な「Cache-Control」ヘッダーがある場合や、独自のアプリ キャッシュ戦略をより詳細に制御したい場合に、Android Volley のキャッシュ戦略を扱う際に役立つ優れたコードを提供します。

キーはHttpHeaderParser.parseCacheHeaders(NetworkResponse response))です。独自のキャッシュ戦略が必要な場合。対応する classparseIgnoreCacheHeaders(NetworkResponse response)に置き換えます。

クラスが JsonObjectRequest を拡張している場合は、JsonObjectRequest に移動して、

@Override
protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
    try {
            String jsonString =new String(response.data, HttpHeaderParser.parseCharset(response.headers));
            return Response.success(new JSONObject(jsonString),HttpHeaderParser.parseCacheHeaders(response));
        }catch (UnsupportedEncodingException e) {
            return Response.error(new ParseError(e));
        }catch (JSONException je) {
            return Response.error(new ParseError(je));
        }
}

HttpHeaderParser.parseCacheHeaders(response)と置き換えますHttpHeaderParser.parseIgnoreCacheHeaders

于 2013-10-11T21:00:49.043 に答える
2

oleksandr_yefremov と skyfishjy も +1 し、json またはその他の文字列ベースの API に適した具体的で再利用可能なクラスをここで提供します。

public class CachingStringRequest extends StringRequest {
    public CachingStringRequest(int method, String url, Response.Listener<String> listener, Response.ErrorListener errorListener) {
        super(method, url, listener, errorListener);
    }

    public CachingStringRequest(String url, Response.Listener<String> listener, Response.ErrorListener errorListener) {
        super(url, listener, errorListener);
    }

    @Override
    protected Response<String> parseNetworkResponse(NetworkResponse response) {
        String parsed;
        try {
            parsed = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
        } catch (UnsupportedEncodingException e) {
            parsed = new String(response.data);
        }
        return Response.success(parsed, parseIgnoreCacheHeaders(response));
    }
}

関数 parseIgnoreCacheHeaders() は、上記の oleksandr_yefremov の回答に由来します。CachingStringRequest クラスは、結果の json が 3 分間 (ライブ) および 24 時間 (期限切れだが利用可能) キャッシュしても問題ない場所で使用します。リクエストの例:

CachingStringRequest stringRequest = new CachingStringRequest(MY_API_URL, callback);

コールバック オブジェクトの onResponse() 関数内で、json を解析します。必要なキャッシング制限を設定します。パラメーター化して、リクエストごとにカスタムの有効期限を追加できます。

お楽しみとして、json をダウンロードし、ダウンロードした情報をレンダリングする単純なアプリでこれを試してください。最初の成功したダウンロードでキャッシュがいっぱいになったら、キャッシュがライブである間に方向を変更すると、高速なレンダリングが見られます (ライブ キャッシュ ヒットの場合、ダウンロードは発生しません)。ここでアプリを強制終了し、キャッシュ ヒットの有効期限が切れるまで 3 分間待ちます (ただし、キャッシュから削除されるまで 24 時間はかかりません)。機内モードを有効にして、アプリを再起動します。Volley エラー コールバックが発生し、「成功した」 onResponse() コールバックがキャッシュされたデータから発生するため、アプリはコンテンツをレンダリングするだけでなく、期限切れのキャッシュからのものであることを認識/警告することもできます。

この種のキャッシングの用途の 1 つは、ローダーやその他の向きの変更を処理する手段を不要にすることです。リクエストが Volley シングルトンを通過し、結果がキャッシュされる場合、向きの変更によって発生する更新は、ローダーなしで Volley によって自動的にキャッシュからすばやくレンダリングされます。

もちろん、これはすべての要件に適合するわけではありません。YMMV

于 2014-09-18T19:53:48.877 に答える