Android的凌空+ JSONObjectRequest缓存缓存、Android、JSONObjectRequest

2023-09-12 03:48:49 作者:喜欢你却说不出口、

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);
    }
}

我希望这片code就足以让我得到的答复隐缓存。我不知道,如果它工作或没有,因为我是假设下,当一个请求被发送:

I was hoping that this piece of code would be enough for me to get implicit caching of responses. I'm not sure if it works or not, because i was under the assumption when a request is sent:

它会先打缓存并发送至onresponse

it would hit the cache first and send that to onresponse

那么当结果来通过从远程服务器,将它提供给onresponse

then when the results come through from the remote server it would provide it to the onresponse

更新:

我想通了如何手动检索缓存和重建成一个JSONObject的,并通过OnResponse功能发送,但这似乎并没有有效的考虑有隐含的缓存。 JsonObjectRequest类应返回的JSONObject作为缓存项,而不是原始的响应数据。

I figured how to manually retrieve the cache and reconstruct it into a JSONObject and send it through OnResponse function but that doesn't seem to efficient considering there is implicit caching. JsonObjectRequest class should return JSONObject as the cached entry instead of raw response data.

但我还是想知道如果我做一些错误的。

But i'm still interested to know if i'm making some mistake.

模糊性完全是由于缺少文件,所以我道歉,如果我想的东西比较明显的。

The ambiguity is solely due to the lack of documentation, so i apologize if i'm missing something quite obvious.

推荐答案

看到这个答案 - Set使用谷歌的凌空过期策略缓存

See this answer - Set expiration policy for cache using Google's Volley

这意味着凌空决定是否缓存响应与否仅基于头的Cache-Control,然后过期,最大生存周期。

This means Volley decides whether to cache response or not based only on headers "Cache-Control" and then "Expires", "maxAge".

你可以做的就是改变这种方法 com.android.volley.toolbox.HttpHeaderParser.parseCacheHeaders(NetworkResponse响应) 而忽略了这些头,设置entry.softTtl和entry.ttl领域的任何值,为你和你的要求类用你的方法。下面是一个例子:

What you could do is change this method com.android.volley.toolbox.HttpHeaderParser.parseCacheHeaders(NetworkResponse response) and ignore these headers, set entry.softTtl and entry.ttl fields to whatever value works for you and use your method in your request class. Here is an example:

/**
 * Extracts a {@link Cache.Entry} from a {@link NetworkResponse}.
 * Cache-control headers are ignored. SoftTtl == 3 mins, ttl == 24 hours.
 * @param response The network response to parse headers from
 * @return a cache entry for the given response, or null if the response is not cacheable.
 */
public static Cache.Entry parseIgnoreCacheHeaders(NetworkResponse response) {
    long now = System.currentTimeMillis();

    Map<String, String> headers = response.headers;
    long serverDate = 0;
    String serverEtag = null;
    String headerValue;

    headerValue = headers.get("Date");
    if (headerValue != null) {
        serverDate = HttpHeaderParser.parseDateAsEpoch(headerValue);
    }

    serverEtag = headers.get("ETag");

    final long cacheHitButRefreshed = 3 * 60 * 1000; // in 3 minutes cache will be hit, but also refreshed on background
    final long cacheExpired = 24 * 60 * 60 * 1000; // in 24 hours this cache entry expires completely
    final long softExpire = now + cacheHitButRefreshed;
    final long ttl = now + cacheExpired;

    Cache.Entry entry = new Cache.Entry();
    entry.data = response.data;
    entry.etag = serverEtag;
    entry.softTtl = softExpire;
    entry.ttl = ttl;
    entry.serverDate = serverDate;
    entry.responseHeaders = headers;

    return entry;
}

在您的要求类使用此方法是这样的:

Use this method in your Request class like this:

public class MyRequest extends com.android.volley.Request<MyResponse> {

    ...

    @Override
    protected Response<MyResponse> parseNetworkResponse(NetworkResponse response) {
        String jsonString = new String(response.data);
        MyResponse MyResponse = gson.fromJson(jsonString, MyResponse.class);
        return Response.success(MyResponse, HttpHeaderParser.parseIgnoreCacheHeaders(response));
    }

}