我知道有很多类似的问题,但是我已经阅读了所有回答,没有一个能够真正帮到我。
我的问题如下:
我正在使用retrofit + okhttp从API获取一些数据,并且想要进行缓存。不幸的是,我没有管理员权限去修改API服务器返回的头部信息。(目前,服务器返回Cache-control: private)
因此,我决定使用okhttp头部欺骗来插入适当的缓存头部。不幸的是,无论我做什么,缓存似乎都无法生效。
我像这样初始化api服务:
int cacheSize = 10 * 1024 * 1024; // 10 MiB
File cacheFile = new File(context.getCacheDir(), "thumbs");
final Cache cache = new Cache(cacheFile, cacheSize);
OkHttpClient client = new OkHttpClient();
client.setCache(cache);
client.interceptors().add(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Response originalResponse = chain.proceed(chain.request());
return originalResponse.newBuilder()
.removeHeader("Access-Control-Allow-Origin")
.removeHeader("Vary")
.removeHeader("Age")
.removeHeader("Via")
.removeHeader("C3-Request")
.removeHeader("C3-Domain")
.removeHeader("C3-Date")
.removeHeader("C3-Hostname")
.removeHeader("C3-Cache-Control")
.removeHeader("X-Varnish-back")
.removeHeader("X-Varnish")
.removeHeader("X-Cache")
.removeHeader("X-Cache-Hit")
.removeHeader("X-Varnish-front")
.removeHeader("Connection")
.removeHeader("Accept-Ranges")
.removeHeader("Transfer-Encoding")
.header("Cache-Control", "public, max-age=60")
//.header("Expires", "Mon, 27 Apr 2015 08:15:14 GMT")
.build();
}
});
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint(API_ROOT)
.setLogLevel(RestAdapter.LogLevel.HEADERS_AND_ARGS)
.setClient(new OkClient(client))
.setConverter(new SimpleXMLConverter(false))
.setRequestInterceptor(new RequestInterceptor() {
@Override
public void intercept(RequestFacade request) {
if (Network.isConnected(context)) {
int maxAge = 60; // read from cache for 2 minutes
request.addHeader("Cache-Control", "public, max-age=" + maxAge);
} else {
int maxStale = 60 * 60 * 24 * 28; // tolerate 4-weeks stale
request.addHeader("Cache-Control",
"public, only-if-cached, max-stale=" + maxStale);
}
}
})
.build();
api = restAdapter.create(ApiService.class);
当然,没有必要删除所有这些头文件,但我想尽可能使响应看起来更加干净,以排除一些来自这些额外头文件的干扰。
如您所见,我尝试了伪造Expires和Date标头(我尝试删除它们,将它们设置为恰好与它们之间的最大年龄差异,并将Expires设置为远期)。 我还尝试了各种Cache-control值,但没有成功。
我确保cacheFile存在,是应用程序可写的目录。
这些是由retrofit直接记录的请求和响应头文件:
Request:
Cache-Control: public, max-age=60
---> END HTTP (no body)
Response:
Date: Mon, 27 Apr 2015 08:41:10 GMT
Server: Apache/2.2.22 (Ubuntu)
Expires: Mon, 27 Apr 2015 08:46:10 GMT
Content-Type: text/xml; charset=UTF-8
OkHttp-Selected-Protocol: http/1.1
OkHttp-Sent-Millis: 1430124070000
OkHttp-Received-Millis: 1430124070040
Cache-Control: public, max-age=60
<--- END HTTP (-1-byte body)
<--- BODY: ...
最后,发生了一件奇怪的事情:某个时刻,缓存工作了几分钟。我得到了合理的命中次数,即使是离线请求也返回了缓存值。(发生在使用此处发布的确切设置时) 但是当我重新启动应用程序时,一切都恢复到“正常状态”(命中计数恒为0)。
如果有人知道这里可能出现什么问题,我会非常感激任何帮助 :)