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);
}
}
我希望这段代码足以让我获得响应的隐式缓存。我不确定它是否工作,因为当发送请求时,我是在假设下进行的:
当结果从远程服务器传来时,它将首先命中缓存并将其发送到onresponse
更新:
我知道如何手动检索缓存并将其重构为JSONObject,然后通过OnResponse函数发送它,但考虑到存在隐式缓存,这似乎并不有效。JsonObjectRequest类应该返回JSONObject作为缓存条目,而不是原始响应数据。
但我还是有兴趣知道我是不是做错了什么。
这种含糊不清完全是由于缺乏文档,所以如果我遗漏了一些非常明显的东西,我道歉。
发布于 2013-05-31 15:46:53
查看此答案- Set expiration policy for cache using Google's Volley
这意味着Volley只根据" cache -Control“和"Expires”、"maxAge“来决定是否缓存响应。
您可以做的是更改此方法com.android.volley.toolbox.HttpHeaderParser.parseCacheHeaders(NetworkResponse response)
并忽略这些头文件,将entry.softTtl
和entry.ttl
字段设置为适合您的任何值,并在请求类中使用您的方法。下面是一个示例:
/**
* 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;
}
在请求类中使用此方法,如下所示:
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));
}
}
发布于 2013-10-12 05:00:49
oleksandr_yefremov提供了很棒的代码,可以帮助你处理安卓截击的缓存策略,特别是当REST API有不正确的cache - control头部时,或者你只是想更多地控制自己的应用缓存策略。
关键是HttpHeaderParser.parseCacheHeaders(NetworkResponse response))
。如果你想拥有自己的缓存策略。将其替换为对应类中的parseIgnoreCacheHeaders(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.parseIgnoreCacheHeaders
替换HttpHeaderParser.parseCacheHeaders(response)
发布于 2014-09-19 03:53:49
+1也适用于oleksandr_yefremov和skyfishjy,并在这里提供了一个具体的、可重用的类,适用于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答案。在生成的json可以缓存3分钟(实时)和24小时(过期但仍然可用)的任何地方使用CachingStringRequest类。示例请求:
CachingStringRequest stringRequest = new CachingStringRequest(MY_API_URL, callback);
在回调对象的onResponse()函数中,解析json。设置您想要的任何缓存限制--您可以对每个请求进行参数化,以添加自定义过期。
为了好玩,可以在一个简单的应用程序中尝试一下,该应用程序下载json并呈现下载的信息。用第一次成功的下载填充缓存后,在缓存处于活动状态时更改方向时,请观察快速渲染(如果实时缓存命中,则不会发生下载)。现在关闭应用程序,等待3分钟,等待缓存命中过期(但不是24小时,将其从缓存中删除),启用飞行模式,然后重新启动应用程序。将发生截击错误回调,并且将从缓存的数据中执行“成功的”onResponse()回调,从而允许您的应用程序既呈现内容,又知道/警告它来自过期的缓存。
这种缓存的一种用途是避免Loaders和其他处理方向变化的方法。如果请求通过Volley singleton,并且结果被缓存,则通过方向更改发生的刷新将从缓存中快速呈现,由Volley自动呈现,而无需Loader。
当然,这并不能满足所有需求。YMMV
https://stackoverflow.com/questions/16781244
复制相似问题