Retrofit2中使用OkHttp3缓存数据

在使用RxJava2+Retrofit2+OkHttp3异步访问网络时,常常需要我们设置超时、设置重试、设置缓存和设置拦截器等。那么本文就是记录并分享一下,实际开发中使用的方式,并对关键部分进行了注释。

首先,我们知道retrofit本身并没有缓存,所以要通过与OKHttp配合可以实现缓存。

接下来,直接看看实现方式:(主要是需要熟练使用OkHttp及其OkHttpClient)

1、构造Retrofit

Retrofit retrofit = new Retrofit.Builder()
        .baseUrl(Common.Base_Api)
        .client(OkHttp3Helper.getOkHttpClient(applicationContext))
        .addConverterFactory(GsonConverterFactory.create())
        .build();

2、使用OkHttpClient,设置缓存的路径、大小,以及使用Interceptor拦截器修改缓存策略

public class OkHttp3Helper {

    public static OkHttpClient getOkHttpClient(Context applicationContext) {
        Interceptor interceptor = new Interceptor() {
            // 读取缓存时,就不会走intercept回调
            @Override
            public okhttp3.Response intercept(Chain chain) throws IOException {
                Request request = chain.request();
                if (NetworkConnectedUtils.notNetworkConnected(applicationContext)) { // 判断网络是否连接
                    request = request.newBuilder().cacheControl(CacheControl.FORCE_CACHE).build();
                }
                okhttp3.Response response = chain.proceed(request);
                if (NetworkConnectedUtils.notNetworkConnected(applicationContext)) {
                    return response.newBuilder() // 长缓存,有效期为7天
                            .header("Cache-Control", "public, only-if-cached, max-stale=" + 60 * 60 * 24 * 7)
                            .removeHeader("Pragma")
                            .build();
                } else {
                    String cacheControl = request.cacheControl().toString();
                    if (TextUtils.isEmpty(cacheControl))
                        cacheControl = "public,max-age=600"; // 短缓存,有效期10分钟
                    return response.newBuilder()
                            .header("Cache-Control", cacheControl)
                            .removeHeader("Pragma") // 清除头信息,因为服务器如果不支持,会返回一些干扰信息,不清除下面无法生效
                            .build();
                }
            }
        };
        File cacheFile = new File(applicationContext.getCacheDir(), "responses");
        Cache cache = new Cache(cacheFile, 1024 * 1024 * 20); // 缓存大小20MB
        return new OkHttpClient.Builder()
                // addNetworkInterceptor添加的是网络拦截器,他会在在request和resposne是分别被调用一次,
                // addInterceptor添加的是application拦截器,他只会在response被调用一次.
                .addInterceptor(interceptor) // 不添加的话,没网络就不会有缓存
                .addNetworkInterceptor(interceptor) // 设置拦截器。
                .cache(cache) // 设置缓存。
                .retryOnConnectionFailure(true)// 设置重试。连接失败后是否重新连接,默认重试一次,若需要重试N次,则要实现拦截器。
                // 设置超时。square官方建议timeout
                .connectTimeout(10, TimeUnit.SECONDS) // 尽量设置得小一些(比如10s),这样可以减小弱网环境下手机的负载,同时对于用户体验也有好处
                .writeTimeout(10, TimeUnit.SECONDS)
                .readTimeout(30, TimeUnit.SECONDS)
                .build();
    }

}

收尾,关于原理或者其他实现方式,网络上有很多讲解的,所以分享本文的目的,只希望能加深理解——“Retrofit2中使用OkHttp3缓存数据”!

猜你喜欢

转载自blog.csdn.net/Agg_bin/article/details/86628340
今日推荐