天天看点

Android之OkHttp源码分析一关键类介绍1.OkHttp关键类和类的作用2.拦截的调用顺序

目录

1.OkHttp关键类和类的作用

1.1.OkHttpClient(请求客户端)

1.2.Request

1.3.RealCall

1.4执行请求相关类

1.5.Dispatcher

1.7.BridgeInterceptor

1.8.CacheInterceptor

1.9.ConnectInterceptor

1.10.CallServerInterceptor

2.拦截的调用顺序

1.OkHttp关键类和类的作用

1.1.OkHttpClient(请求客户端)

OkHttpClient是用于生产Call {@linkplain Call calls}的工厂,可以发送请求和读取请求返回的响应信息;

a.OkHttpClients应该被公用的

当我们创建一个{@code OkHttpClient}实例时并且复用它为了所有的HTTP请求调用时将是更高效的。这是因为彼此客户端都拥有自己的连接池和线程池。复用连接和线程将减少延迟并节省内存。相反,为每一个请求都创建客户端将是浪费资源。使用{@code new OkHttpClient()}创建一个有默认配置公用的实例,代码如下;

{@code

    // The singleton HTTP client.

    public final OkHttpClient client = new OkHttpClient();

}

或者使用 {@code new OkHttpClient.Builder()}去创建一个有定制配置的公用的实例,代码如下;

{@code

    // The singleton HTTP client.

    public final OkHttpClient client = new OkHttpClient.Builder()

        .addInterceptor(new HttpLoggingInterceptor())

        .cache(new Cache(cacheDir, cacheSize))

        .build();

}

b.使用newBuilder()定制你的客户端

你能使用{@link #newBuilder()}定制一个共享的OkHttpClient的实例。这个将创建一个共享相同连接池,线程池和配置的客户端。使用builder方法去配置为了特殊用途的派生客户端。这个展示一个500毫秒超时的调用例子:

{@code

    OkHttpClient eagerClient = client.newBuilder()//判断出来的客户端-共享连接池,线程池等

        .readTimeout(500, TimeUnit.MILLISECONDS)

        .build();

    Response response = eagerClient.newCall(request).execute();

  }

c.关闭连接或者线程池不是必须的

如果它们保持空闲的,线程和连接将被自动释放。但是,如果您正在编写一个需要积极释放未使用的资源的应用程序,您可以这样做。

关闭dispatcher的线程池服务使用{@link ExecutorService#shutdown shutdown()}。这也会导致将来客户被拒绝的调用。

{@code

      client.dispatcher().executorService().shutdown();

 }

d.使用{@link ConnectionPool#evictAll() evictAll()}清理连接池。注意,那个连接池的后台线程不能立即退出。

{@code

      client.connectionPool().evictAll();

 }

e.如果你的客户端有一个缓存,调用 {@link Cache#close close()}。注意去创建一个被关闭的缓存的调用将是错误的,并且这样将引起崩溃。

{@code

     client.cache().close();

}

f.OkHttp为了HTTP/2连接也使用后台线程。如果它们空闲,这些连接将自动退出

1.2.Request

包装的一个HTTP请求,如果body是null或者它自己不可变,类的实例也是不可变的;

//包含请求的如下信息
  private final HttpUrl url;//请求的url
  private final String method;//请求的方法
  private final Headers headers;//请求头
  private final RequestBody body;//请求的body
  private final Object tag;//请求的标记
           

1.3.RealCall

RealCall是一个封装已经准备去执行的请求的调用。这个调用可以被取消。作为这个对象表示单个请求/响应对(流),不能执行两次。

1.4执行请求相关类

调用RealCall的execute()执行请求时,查看下面RealCall类中请求的方法如下:

@Override public Response execute() throws IOException {
    synchronized (this) {
      if (executed) throw new IllegalStateException("Already Executed");
      executed = true;
    }
    try {
      client.dispatcher().executed(this);
      Response result = getResponseWithInterceptorChain();
      if (result == null) throw new IOException("Canceled");
      return result;
    } finally {
      client.dispatcher().finished(this);
    }
  }
           

我们会看到具体执行网络请求关键步骤类的部分,主要有Dispatcher类和RealCall类下getResponseWithInterceptorChain()方法下关键的拦截器类

private 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 (!retryAndFollowUpInterceptor.isForWebSocket()) {
      interceptors.addAll(client.networkInterceptors());
    }
    interceptors.add(new CallServerInterceptor(
        retryAndFollowUpInterceptor.isForWebSocket()));

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

RetryAndFollowUpInterceptor,BridgeInterceptor,CacheInterceptor,ConnectInterceptor,CallServerInterceptor。

1.5.Dispatcher

每个Dispatcher使用一个{@ Link ExecutorService }在内部运行调用。如果你提供你的自己的executor,它应该能够运行 {@linkplain #getMaxRequests 配置的最大}数量的并发调用。

1.6.RetryAndFollowUpInterceptor

这个拦截器可以从请求失败和重定向中按需要恢复。 它可能抛出异常 {@link IOException} 如何调用被取消。

1.7.BridgeInterceptor

从应用程序代码到网络代码的桥梁。首先,它从用户请求建立网络请求,然后继续调用网络请求。最后,根据网络响应建立用户响应。

1.8.CacheInterceptor

服务缓存中的请求并向缓存写入响应。

1.9.ConnectInterceptor

打开到目标服务器的连接,并执行下一个拦截器。

1.10.CallServerInterceptor

这是最后一个拦截器,它将调用一个到服务器的网络请求。

2.拦截的调用顺序

Android之OkHttp源码分析一关键类介绍1.OkHttp关键类和类的作用2.拦截的调用顺序

继续阅读