Okhttp--缓存的加入方式

Okhttp是由Sqare公司开发的开源网络访问库,目前在Android和Java开发中有着广泛的应用。在Android开发中和Retrofit结合可以非常方便地调用网络接口。

使用缓存可以让我们的app不用长时间地显示令人厌烦的加载圈,提高了用户体验,而且还节省了流量,在数据更新不是很频繁的地方使用缓存就非常有必要了。想要加入缓存不需要我们自己来实现,Okhttp已经内置了缓存,默认是不使用的,如果想使用缓存我们需要手动设置。

Cache-control常用参数

  • max-age:这个参数告诉浏览器将页面缓存多长时间,超过这个时间后才再次向服务器发起请求检查页面是否有更新。
  • no-cache:是会被缓存的,只不过每次在向客户端(浏览器)提供响应数据时,缓存都要向服务器评估缓存响应的有效性。
  • no-store:数据不在硬盘中临时保存,这个才是响应不被缓存的意思。
  • max-stale:指示客户机可以接收超出超时期间的响应消息。如果指定max-stale消息的值,那么客户机可以接收超出超时期指定值之内的响应消息。

服务器支持缓存

如果服务器支持缓存,请求返回的Response会带有这样的Header:Cache-Control, max-age=xxx,这种情况下我们只需要手动给okhttp设置缓存就可以让okhttp自动帮你缓存了。这里的max-age的值代表了缓存在你本地存放的时间,可以根据实际需要来设置其大小。

首先我们要提供了一个文件路径用来存放缓存,出于安全性的考虑,在Android中我们推荐使用Context.getCacheDir()来作为缓存的存放路径,另外还需要指定缓存的大小就可以创建一个缓存了。如下所示:

public Cache provideCache() {
        return new Cache(mContext.getCacheDir(), 10240*1024);
    }

创建了这个缓存后我们还需要将其设置到okttpClient对象里面:

OkHttpClient newClient = new OkHttpClient.newBuilder()
               .cache(cache)
               .connectTimeout(20, TimeUnit.SECONDS)
               .readTimeout(20, TimeUnit.SECONDS)
               .build();

服务器不支持缓存

如果服务器不支持缓存就可能没有指定这个头部,或者指定的值是如no-store等,但是我们还想在本地使用缓存的话要怎么办呢?这种情况下我们就需要使用Interceptor来重写Respose的头部信息,从而让okhttp支持缓存。

如下所示,我们重写的Response的Cache-Control字段

public class CacheInterceptor implements Interceptor {
    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        Response response = chain.proceed(request);
        Response response1 = response.newBuilder()
                .removeHeader("Pragma")
                .removeHeader("Cache-Control")
                //cache for 30 days
                .header("Cache-Control", "max-age=" + 3600 * 24 * 30)
                .build();
        return response1;
    }
}

然后将该Intercepter作为一个NetworkInterceptor加入到okhttpClient中:

OkHttpClient newClient = new OkHttpClient.newBuilder()
        .addNetworkInterceptor(new CacheInterceptor())
        .cache(cache)
        .connectTimeout(20, TimeUnit.SECONDS)
        .readTimeout(20, TimeUnit.SECONDS)
        .build();

这样我们就可以在服务器不支持缓存的情况下使用缓存了。

官方建议缓存方法

官方建议用CacheControl这个类来进行缓存策略的制定。

  • noCache();//不使用缓存,用网络请求
  • noStore();//不使用缓存,也不存储缓存
  • onlyIfCached();//只使用缓存
  • noTransform();//禁止转码
  • maxAge(10, TimeUnit.MILLISECONDS);//设置超时时间为10ms。
  • maxStale(10, TimeUnit.SECONDS);//超时之外的超时时间为10s
  • minFresh(10, TimeUnit.SECONDS);//超时时间为当前时间加上10秒钟。

不同于拦截器设置缓存,CacheControl是针对Request的,所以它可以针对每个请求设置不同的缓存策略。比如图片和新闻列表。下面代码展示如何用CacheControl设置一个30秒的超时时间。

OkHttpClient client = new OkHttpClient().newBuilder().build();
        CacheControl cc = new CacheControl.Builder()
                .maxAge(30, TimeUnit.SECONDS)
                .build();
        Request request = new Request.Builder()
                .url("http://ngudream.com")
                .cacheControl(cc)
                .build();
        try {
            client.newCall(request).execute();
        } catch (IOException e) {
            e.printStackTrace();
        }

完整代码见github:

A simple Android app shows Hearthstone cards with okhttp, retrofit, dagger2 and Meterail Design

地址:https://github.com/Chaoba/HearthstoneCards

[转]http://blog.csdn.net/copy_yuan/article/details/51524907

文章目录
  1. 1. Cache-control常用参数
  2. 2. 服务器支持缓存
  3. 3. 服务器不支持缓存
  4. 4. 官方建议缓存方法
|