Retrofit2网络框架的使用(二)扩展

我们学习了Retrofit的基本使用后,我们知道Retrofit内部其实还是由Okhttp实现的,Retrofit只是对其进行了一层封装,下面我们队Retrofit使用中常见的问题进行整理。

Retrofit的扩展使用

一、拦截器

拦截器是一种强大的机制,可以监视,重写和重试调用,记录传出请求和传入响应,即可以实现网络监听、请求以及响应重写、请求失败重试等功能。

引用官网的一张图,下图标出了Application Interceptor和Network Interceptor两种拦截器,一般我们需要对Request或Response进行操作就是通过这两类拦截器来完成的。

image

拦截器可以以application或者network两种方式注册,可以调用addInterceptor()以及addNetworkInterceptor方法进行注册,我们对这些进行简单的学习。

addInterceptor() :

  • 无法操作中间的响应,只能操作第一次请求以及返回的最终结果
  • 监听请求的最原始意图(请求头,请求体等),无法操作OkHttp为我们自动添加的额外的请求头
  • 总是只调用一次,即使HTTP响应是从缓存中获取
  • 如果本地有缓存,可以从本地缓存中获取响应实例返回给客户端。

addNetworkInterceptor() :

  • 能够详尽的追踪访问链接的重定向
  • 短时间内的网络访问,它将不执行缓存过来的回应
  • 监测整个网络过程的数据流量
  • 当网络短路而返回缓存响应时不被调用
  • 携带请求来访问连接
  • 能从缓存池中获取缓存对象返回给客户端,通过请求服务的方式获取响应(Chain.proceed())

二、基本使用,输出日志

我们在开发的应用经常是需要与网络互连进行交互的,但是我们怎么准确的输出我们请求的信息?Okhttp为我们提供了logging-interceptor方便我们输出对应的日志信息github-khttp-logging-interceptor。

1、添加依赖

implementation 'com.squareup.okhttp3:logging-interceptor:3.11.0'

2、设置日志级别

  • HttpLoggingInterceptor.Level.HEADERS// 开启请求头
  • HttpLoggingInterceptor.Level.BODY//开启body日志
  • HttpLoggingInterceptor.Level.BASIC //基础输出
  • HttpLoggingInterceptor.Level.NONE

添加网络拦截器

 //基础输出
 OkHttpClient client = new OkHttpClient.Builder()
    .addNetworkInterceptor(new HttpLoggingInterceptor()
    .setLevel(HttpLoggingInterceptor.Level.BASIC))
    .build();

添加应用拦截器

OkHttpClient client = new OkHttpClient.Builder()
    .addInterceptor(new HttpLoggingInterceptor()
    .setLevel(HttpLoggingInterceptor.Level.BASIC))
    .build();

3、使用方法

Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("url")
    .client(client)
    .build();

三、增加统一的header

我们通过在请求网络的接口中设置header只对当前的定义的请求方法有效,而不对所有请求有效,因此我们通过设置统一的Header方便调用

OkHttpClient client = new OkHttpClient.Builder()
    .addInterceptor(new Interceptor() {
        @Override
        public okhttp3.Response intercept(Chain chain) throws IOException {
            Request request=new Request.Builder()
                .addHeader("key","value")
                .addHeader("key","value")
                .build();
            return chain.proceed(request);
         }
    })
.build();
//使用通过client方法调用,与上面相同

四、设置Cookie

//记录下正确姿势
OkHttpClient client = new OkHttpClient.Builder()
    .cookieJar(new CookieJar() {
        private final HashMap> cookieStore = new HashMap<>();
        //Tip:這裡key必須是String
        @Override
        public void saveFromResponse(HttpUrl url, List cookies) {
            //可以持久化保存至本地
            cookieStore.put(url.host(), cookies);
        }
        @Override
        public List loadForRequest(HttpUrl url) {
            List cookies = cookieStore.get(url.host());
            return cookies != null ? cookies : new ArrayList();
        }
    })
    .build();
//使用与之前一致

五、设置缓存Cache

通过判断是否有网络,判断缓存时间

public class CacheInterceptor implements Interceptor {

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        if (!NetworkUtils.isNetworkConnected(App.getInstance())) {
            request = request.newBuilder()
                    .cacheControl(CacheControl.FORCE_CACHE)
                    .build();
        }
        Response response = chain.proceed(request);
        if (NetworkUtils.isNetworkConnected(App.getInstance())) {
            int maxAge = 60 * 60 * 24 ;
            // 有网络时, 不缓存, 最大保存时长为1小时
            response.newBuilder()
                    .header("Cache-Control", "public, max-age=" + maxAge)
                    .removeHeader("Pragma")
                    .build();
        } else {
            // 无网络时,设置超时为4周
            int maxStale = 60 * 60 * 24 * 28;
            response.newBuilder()
                    .header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
                    .removeHeader("Pragma")
                    .build();
        }
        return response;
    }
}

使用

Interceptor cacheInterceptor = new CacheInterceptor();
 OkHttpClient client= new OkHttpClient.Builder()
    .addInterceptor(cacheInterceptor)
    .build();
//使用与之前一致

你可能感兴趣的:(Retrofit2网络框架的使用(二)扩展)