使用HttpResponsecache的脱机缓存时出现FileNotFoundException

时间:2013-12-26 17:18:37

标签: android caching

我正在使用HttpResponseCache在我的Android应用中启用响应缓存(针对Web请求),并且脱机缓存无法正常工作。 我正在进行离线缓存,documentation告诉我这样做。

在我的Application类中,在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"被添加到请求标头中(代码为:{ {1}})

当存在连接并且应用程序点击Web服务器以查看是否存在更新版本的JSON时,缓存工作“正常”(具有轻微的奇怪行为)。当Web服务器回答“未更改”时,缓存可以正常工作。

问题是当我没有连接并使用标题connection.addRequestProperty("Cache-Control", "only-if-cached");时。在这种情况下,我收到"Cache-Control", "only-if-cached"。这很尴尬,因为缓存的implementation code可能将响应存储在请求URL上使用哈希函数命名的文件中,而不是url本身。

有谁知道我可以做什么或我的实施有什么问题?

ps:上面,我说“可能使用哈希函数”,因为我无法找到com.android.okhttp.HttpResponseCache对象(java.io.FileNotFoundException: https://api.example.com/movies.json委托缓存调用的类)的实现。如果有人找到了,请告诉我在哪里看:)

ps2:即使我在android.net.http.HttpResponseCache标题中添加了max-stale参数,它仍然无效。

ps3:我显然在api 14 +上测试了它。

ps4:虽然我正在访问“https://”URL地址,但当URL只是普通的“http://”地址时,会出现同样的行为。

1 个答案:

答案 0 :(得分:3)

事实证明问题出在我的Web服务器给出的响应中max-age指令的Cache-control值。它具有以下值:Cache-Control: max-age=0, private, must-revalidate。使用此指令,我的服务器告诉缓存,即使缓存为0秒,也可以从缓存中使用响应。所以,我的连接没有使用任何缓存的响应。

知道max-age是以秒为单位指定的,我所要做的就是将值更改为:Cache-Control: max-age=600, private, must-revalidate!在那里,现在我有10分钟的缓存。

编辑:如果您想使用请求的max-stale指令的陈旧响应,则不应像在我的网络服务器中那样在响应中使用must-revalidate指令。 / p>