我使用HttpResponseCache在我的android应用程序中启用响应缓存(用于web请求),并且离线缓存无法工作。我正在执行文档要求我做的离线缓存。
在我的应用程序类中,在onCreate方法中,我打开缓存时:
try {
long httpCacheSize = 10 * 1024 * 1024; // 10 MiB
File httpCacheDir = new File(getCacheDir(), "http");
Class.forName("android.net.http.HttpResponseCache")
.getMethod("install", File.class, long.class)
.invoke(null, httpCacheDir, httpCacheSize);
} catch (Exception httpResponseCacheNotAvailable) {}在我的HttpConnection类中,我使用以下方法获得JSON:
private String sendHttpGet(boolean cacheOnly) throws Exception {
URL url = new URL(getUrlCompleta());
HttpURLConnection urlConnection = null;
String retorno = null;
try {
urlConnection = (HttpURLConnection) url.openConnection();
if(urlConnection == null)
throw new Exception("Conn obj is null");
fillHeaders(urlConnection, cacheOnly);
InputStream in = new BufferedInputStream(urlConnection.getInputStream(), 8192);
retorno = convertStream(in);
in.close();
urlConnection.disconnect();
if(retorno != null)
return retorno;
} catch(IOException e) {
throw e;
} finally {
if(urlConnection != null)
urlConnection.disconnect();
}
throw new Exception();
}其中,convertStream方法只是将一个InputStream解析为一个String。方法fillHeaders在请求上放置一个令牌(出于安全原因),如果参数cacheOnly是true,则将标头"Cache-Control", "only-if-cached"添加到请求头(代码:connection.addRequestProperty("Cache-Control", "only-if-cached");)中。
当存在连接时,缓存工作“很好”(有一些奇怪的行为),并且应用程序访问web服务器只是为了查看是否有更新版本的JSON。当web服务器回答“什么都没有改变”时,缓存就会工作。
问题是当我没有连接并且使用头"Cache-Control", "only-if-cached"时。在这种情况下,我会收到一个java.io.FileNotFoundException: https://api.example.com/movies.json。这很尴尬,因为缓存的实施代码可能将响应存储在请求url上使用散列函数命名的文件中,而不是url本身。
有人知道我能做什么或者我的实现有什么问题吗?
ps:上面,我说“可能使用散列函数”,因为我找不到com.android.okhttp.HttpResponseCache对象的实现( android.net.http.HttpResponseCache委托缓存调用的类)。如果有人找到了,请告诉我在哪里看:)
ps2:即使我在Cache-Control头中添加了一个max-stale参数,它仍然不能工作。
ps3:很明显,我在api 14+上测试了它。
Https://“:虽然我访问的是一个"http://”URL地址“,但当该URL只是一个普通的”http://“地址”时,也会发生相同的行为。
发布于 2014-01-15 16:20:43
事实证明,问题在于我的web服务器所给出的响应中Cache-control指令的Cache-control值。它具有以下值:Cache-Control: max-age=0, private, must-revalidate。有了这个指令,我的服务器就会对缓存说,即使响应已经存在了0秒钟,也可以从缓存中使用。所以,我的连接没有使用任何缓存的响应。
知道最大年龄是在秒内指定的,我所要做的就是将值更改为:Cache-Control: max-age=600, private, must-revalidate!在这里,现在我有一个10分钟的缓存。
编辑:如果您想使用陈旧的响应,使用请求的max-stale指令,就不应该像我在with服务器中那样在响应中使用must-revalidate指令。
https://stackoverflow.com/questions/20788568
复制相似问题