Android okhttp 获取缓存响应

标签 android caching okhttp

我不是处理 http 的专家,但我想完成的是:

如果响应在缓存中返回缓存,如果不返回网络响应就这么简单。

但问题是响应代码始终为 504,但我确定它已被缓存,因此据我了解它应该返回 != 504,该代码位于“doGetRequest”方法中。

我的 okhttp 客户端:

public class RestAsyncHttpClient {

/* Constants */
private static final String TAG = "RestAsyncHttpClient";
private static long HTTP_CACHE_SIZE = 10 * 1024 * 1024; // 10 MiB
private static final String DISK_CACHE_SUBDIR = "cacheApi";

/* Properties */
private static OkHttpClient mHttpClient;
private static Cache cache;
private static RestAsyncHttpClient instance = null;
private Context context;

public static RestAsyncHttpClient getInstance() {
    if (instance == null) {
        instance = new RestAsyncHttpClient();
    }
    return instance;
}

/**
 * Initialize HttpClient
 */
public void initialize(Context context) {
    setContext(context);

    mHttpClient = new OkHttpClient();

    configureSslSocketFactory();

    configureCache();

    configureTimeouts();
}

private void setContext(Context context) {
    this.context = context;
}

private void configureSslSocketFactory() {
    mHttpClient.setSslSocketFactory(HttpsURLConnection.getDefaultSSLSocketFactory());
}

public static void doGetRequest(String url, Callback callback) throws IOException {
    Request cachedRequest = new Request.Builder()
            .cacheControl(new CacheControl.Builder().onlyIfCached().build())
            .url(url)
            .build();
    Response forceCacheResponse = mHttpClient.newCall(cachedRequest).execute();
    if (forceCacheResponse.code() != 504) {
        // The resource was cached! Show it.
        callback.onResponse(forceCacheResponse);

    } else {
        Request networkRequest = new Request.Builder().url(url).build();
        mHttpClient.newCall(networkRequest).enqueue(callback);
    }
}

private void configureCache() {
    if (cache == null)
        cache = createHttpClientCache(context);

    mHttpClient.setCache(cache);
}

private static Cache createHttpClientCache(Context context) {
    try {
        File cacheDir = context.getDir("cache_api", Context.MODE_PRIVATE);
        return new Cache(cacheDir, HTTP_CACHE_SIZE);

    } catch (IOException exp) {
        LogHelper.error(TAG, "Couldn't create http cache because of IO problem.", exp);
        return null;
    }
}

private void configureTimeouts() {
    mHttpClient.setConnectTimeout(10, TimeUnit.SECONDS);
    mHttpClient.setWriteTimeout(35, TimeUnit.SECONDS);
    mHttpClient.setReadTimeout(35, TimeUnit.SECONDS);
}

我的缓存正在被填充,因此当没有可用连接时它应该从缓存中读取。 cache files

来自服务器的响应头:

  • 连接:关闭
  • 内容类型:application/json;字符集=iso-8859-1
  • 日期:2015 年 3 月 23 日星期一 11:04:44 GMT
  • 服务器:Apache
  • 传输编码:分块
  • X-Powered-By:Servlet/2.5 JSP/2.1

请求 header :

  • 接受:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8
  • 接受编码:gzip、deflate、sdch
  • 接受语言:pt-PT,pt;q=0.8,en-US;q=0.6,en;q=0.4,fr;q=0.2
  • 缓存控制:最大年龄=0
  • 连接:保持 Activity 状态
  • 主持人:cantShare:448
  • 用户代理:Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML,如 Gecko)Chrome/41.0.2272.101 Safari/537.36

最佳答案

当你得到一个响应时,你需要完整地读取它,否则它不会被缓存。这是因为 OkHttp 只有在您读完它的主体时才会将响应提交给缓存。

你不需要 504 的特殊情况。只需定期发出请求,它会在可能的情况下使用缓存。

关于Android okhttp 获取缓存响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29194983/

相关文章:

android相机导致空指针异常

android - 谷歌翻译使用哪种 TTS?有没有办法在 Android 应用程序中也使用此 TTS?

android - 从相机获取图像结果数据 onActivityResult 中为空

文件缓存选项

java - OkHttp 和 Retrofit 中异步操作的 ThreadPoolExecutor 使用差异

android - 为 Android 开发 PhoneGap - 不同屏幕尺寸/像素密度的最佳实践

ios - 如何在UIWebView中启用缓存?

google-app-engine - 我怎样才能控制 WebKit 中的 Google App Engine 缓存行为(etags 变得疯狂)?

android - Okhttp4,无法访问 'body' : it is package-private in 'Response'

java - 哪个是在android中将多张图片上传到服务器的最佳方式