回顾

OkHttp3学习(二):发送一个请求中 我们看到了当我们发送一个请求时,通过client.newCall(request)来创建一个RealCall实例,当我们调用RealCallexecute()的时候会调用client对象的dispatcherexecute()方法来执行这个RealCall。当我们调用了RealCallenqueue()方法之后会在内部调用Client对象的dispatcherexecute()方法时创建一个AsyncCall对象,并执行这个AsyncCallexecute方法。不管是client.newCall(request).execute()还是client.newCall(request).enqueue(new Callback(){})我们会发现对应的Call的execute()都会得到执行。

execute()

既然RealCallAsyncCallexecute()都会得到执行,那他们又有什么共同之处呢,相应又是怎么获得的呢?
这是RealCallexecute() 去除了部分代码之后的

 @Override public Response execute() throws IOException {
    captureCallStackTrace();
    try {
      client.dispatcher().executed(this);
      Response result = getResponseWithInterceptorChain();
      return result;
    } finally {
      client.dispatcher().finished(this);
    }
  }

这是AsyncCall去掉部分代码后的execute()

 @Override protected void execute() {
      try {
        Response response = getResponseWithInterceptorChain();
        if (retryAndFollowUpInterceptor.isCanceled()) {
          responseCallback.onFailure(RealCall.this, new IOException("Canceled"));
        } else {
          responseCallback.onResponse(RealCall.this, response);
        }
      } catch (IOException e) {
       //...
      } finally {
        client.dispatcher().finished(this);
      }
    }

在这两个代码中我们看到。请求的响应(Responce)都是通过getResponseWithInterceptorChain()方法获取的。其代码是这样的:

Response getResponseWithInterceptorChain() throws IOException {
    // Build a full stack of interceptors.
    List<Interceptor> interceptors = new ArrayList<>();
    interceptors.addAll(client.interceptors());
    interceptors.add(retryAndFollowUpInterceptor);
    interceptors.add(new BridgeInterceptor(client.cookieJar()));
    interceptors.add(new CacheInterceptor(client.internalCache()));
    interceptors.add(new ConnectInterceptor(client));
    if (!forWebSocket) {
      interceptors.addAll(client.networkInterceptors());
    }
    interceptors.add(new CallServerInterceptor(forWebSocket));

    Interceptor.Chain chain = new RealInterceptorChain(
        interceptors, null, null, null, 0, originalRequest);
    return chain.proceed(originalRequest);
  }

在这些代码中我们看到了一堆的Interceptor那么这又是个什么鬼呢?

Interceptor

官方关于Interceptor的介绍:点这里
图片描述
看下这个图。看下这个例子自定义一个Inteceptor应该不成问题了。例子在文档中有。

/** This interceptor compresses the HTTP request body. Many webservers can't handle this! */
final class GzipRequestInterceptor implements Interceptor {
  @Override public Response intercept(Interceptor.Chain chain) throws IOException {
    Request originalRequest = chain.request();
    if (originalRequest.body() == null || originalRequest.header("Content-Encoding") != null) {
      return chain.proceed(originalRequest);
    }

    Request compressedRequest = originalRequest.newBuilder()
        .header("Content-Encoding", "gzip")
        .method(originalRequest.method(), gzip(originalRequest.body()))
        .build();
    return chain.proceed(compressedRequest);
  }

  private RequestBody gzip(final RequestBody body) {
    return new RequestBody() {
      @Override public MediaType contentType() {
        return body.contentType();
      }

      @Override public long contentLength() {
        return -1; // We don't know the compressed length in advance!
      }

      @Override public void writeTo(BufferedSink sink) throws IOException {
        BufferedSink gzipSink = Okio.buffer(new GzipSink(sink));
        body.writeTo(gzipSink);
        gzipSink.close();
      }
    };
  }
}

通过下面的方法将一个自定义的Inteceptor加入到请求中。

         OkHttpClient client= new OkHttpClient
                .Builder()
                .addInterceptor(new Interceptor() {
                    @Override
                    public Response intercept(Chain chain) throws IOException {
                     
                        return null;
                    }
                })
                .addNetworkInterceptor(new Interceptor() {
                    @Override
                    public Response intercept(Chain chain) throws IOException {
                        return null;
                    }
                }).build();

Magicer
246 声望11 粉丝

[链接]