OKHttp原码分析(五)之Interceptor

一,概述

在上篇blog中可知:在RealCall的getResponseWithInterceptorChain方法中创建了许多不同类型的Interceptor对象。然后在RealInterceptorChain对象的proceed方法中有调用了Interceptor对象的intercept方法,最终返回Response对象。

Interceptor称为拦截器,这是OKHttp中的一个机制,它的作用是:可以对请求进行转换,重试,重写等操作。

Interceptor是一个接口,它的实现类有:
1. ConnectInterceptor:连接拦截器。
2. CallServerInterceptor:请求服务器拦截器
3. CacheInterceptor:缓存拦截器
4. BridgeInterceptor:桥梁拦截器。
Interceptor是一个接口,可以根据需要自定义拦截器。

下面看几个重要的拦截器。

二ConnectInterceptor类分析

这个类的源码不多,重要的是intercept方法,intercept方法的源码是:

public Response intercept(Chain chain) throws IOException {
    RealInterceptorChain realChain = (RealInterceptorChain) chain;
    Request request = realChain.request();
    StreamAllocation streamAllocation = realChain.streamAllocation();

    boolean doExtensiveHealthChecks = !request.method().equals("GET");
    HttpStream httpStream = streamAllocation.newStream(client, doExtensiveHealthChecks);
    RealConnection connection = streamAllocation.connection();

    return realChain.proceed(request, streamAllocation, httpStream, connection);
}

分析:

  1. 这个方法中创建了两个重要的对象,HttpStream 和RealConnection 。这两个对象是请求协议和连接的核心类,后面做讲解。
  2. 这里又调用了realChain的proceed方法。realChain就是RealInterceptorChain对象,此时index肯定不等于0。该方法的意思是:该拦截器不做实际请求,而是处理后调用下一个拦截器,让下一个拦截器进行处理。

三CallServerInterceptor类分析

这个类是网络请求的本质。它的intercept方法源码如下:

   public Response intercept(Chain chain) throws IOException {
    HttpStream httpStream = ((RealInterceptorChain) chain).httpStream();
    StreamAllocation streamAllocation = ((RealInterceptorChain) chain).streamAllocation();
    Request request = chain.request();

    long sentRequestMillis = System.currentTimeMillis();
    httpStream.writeRequestHeaders(request);//写请求头

    if (HttpMethod.permitsRequestBody(request.method()) && request.body() != null) {
      Sink requestBodyOut = httpStream.createRequestBody(request, request.body().contentLength());
      BufferedSink bufferedRequestBody = Okio.buffer(requestBodyOut);
      request.body().writeTo(bufferedRequestBody);//写请求体
      bufferedRequestBody.close();
    }
    httpStream.finishRequest();
    Response response = httpStream.readResponseHeaders()
        .request(request)
        .handshake(streamAllocation.connection().handshake())
        .sentRequestAtMillis(sentRequestMillis)
        .receivedResponseAtMillis(System.currentTimeMillis())
        .build();//得到response对象

    if (!forWebSocket || response.code() != 101) {
      response = response.newBuilder()
          .body(httpStream.openResponseBody(response))
          .build();//添加ResponseBody对象
    }
    return response;//返回response对象。
  }

这个类是网络请求的核心代码,写入了请求体,也得到了response对象。

写入请求体使用的是RequestBody的writeTo方法,调用RequestBody的writeTo方法时需要传递一个BufferedSink 对象,这个对象是通过httpStream类的createRequestBody方法得到的。这里我们先记住,在下一篇blog中再分析httpStream类。

四,总结

1,在ConnectInterceptor类中创建了HttpStream对象 和RealConnection 对象。
2,在CallServerInterceptor中请求网络,创建response对象,并返回response对象。

猜你喜欢

转载自blog.csdn.net/fightingxia/article/details/71257854