OKhttp源码解析---OkHttpClient创建

来源:互联网 发布:知不足而奋进 编辑:程序博客网 时间:2024/06/07 14:15

OkHttpC客户端是通过new OkHttpClient()创建的,我们看下里面都做了什么

首先是一些static的初始化

private static final List<Protocol> DEFAULT_PROTOCOLS = Util.immutableList(      Protocol.HTTP_2, Protocol.SPDY_3, Protocol.HTTP_1_1);  private static final List<ConnectionSpec> DEFAULT_CONNECTION_SPECS = Util.immutableList(      ConnectionSpec.MODERN_TLS, ConnectionSpec.COMPATIBLE_TLS, ConnectionSpec.CLEARTEXT);  static {    Internal.instance = new Internal() {      @Override public void addLenient(Headers.Builder builder, String line) {        builder.addLenient(line);      }      @Override public void addLenient(Headers.Builder builder, String name, String value) {        builder.addLenient(name, value);      }      @Override public void setCache(OkHttpClient.Builder builder, InternalCache internalCache) {        builder.setInternalCache(internalCache);      }      @Override public boolean connectionBecameIdle(          ConnectionPool pool, RealConnection connection) {        return pool.connectionBecameIdle(connection);      }      @Override public RealConnection get(          ConnectionPool pool, Address address, StreamAllocation streamAllocation) {        return pool.get(address, streamAllocation);      }      @Override public void put(ConnectionPool pool, RealConnection connection) {        pool.put(connection);      }      @Override public RouteDatabase routeDatabase(ConnectionPool connectionPool) {        return connectionPool.routeDatabase;      }      @Override public StreamAllocation callEngineGetStreamAllocation(Call call) {        return ((RealCall) call).streamAllocation();      }      @Override      public void apply(ConnectionSpec tlsConfiguration, SSLSocket sslSocket, boolean isFallback) {        tlsConfiguration.apply(sslSocket, isFallback);      }      @Override public HttpUrl getHttpUrlChecked(String url)          throws MalformedURLException, UnknownHostException {        return HttpUrl.getChecked(url);      }      @Override public void setCallWebSocket(Call call) {        ((RealCall) call).setForWebSocket();      }    };  }
这里主要是一些http协议和连接配置,然后是初始化了一个Internal.instance的变量,这个变量我们后面会用到。

接下来看下OkHttpClient的构造函数

  public OkHttpClient() {    this(new Builder());  }

Builder是它的内部类

public Builder() {      dispatcher = new Dispatcher();      protocols = DEFAULT_PROTOCOLS;      connectionSpecs = DEFAULT_CONNECTION_SPECS;      proxySelector = ProxySelector.getDefault();      cookieJar = CookieJar.NO_COOKIES;      socketFactory = SocketFactory.getDefault();      hostnameVerifier = OkHostnameVerifier.INSTANCE;      certificatePinner = CertificatePinner.DEFAULT;      proxyAuthenticator = Authenticator.NONE;      authenticator = Authenticator.NONE;      connectionPool = new ConnectionPool();      dns = Dns.SYSTEM;      followSslRedirects = true;      followRedirects = true;      retryOnConnectionFailure = true;      connectTimeout = 10_000;      readTimeout = 10_000;      writeTimeout = 10_000;    }
这里主要是一些变量的初始化。

Dispatcher是用来调度异步请求执行的,我们可以看下它的一些成员变量

  private int maxRequests = 64;  private int maxRequestsPerHost = 5;  private Runnable idleCallback;  /** Executes calls. Created lazily. */  private ExecutorService executorService;  /** Ready async calls in the order they'll be run. */  private final Deque<AsyncCall> readyAsyncCalls = new ArrayDeque<>();  /** Running asynchronous calls. Includes canceled calls that haven't finished yet. */  private final Deque<AsyncCall> runningAsyncCalls = new ArrayDeque<>();  /** Running synchronous calls. Includes canceled calls that haven't finished yet. */  private final Deque<RealCall> runningSyncCalls = new ArrayDeque<>();
maxRequestsPerHost说明当前连接请求地址的连接的最大数量,而maxRequests是总的最大连接数

ProxySelector是连接代理服务器,它可以它根据不同的连接使用不同的代理服务器。系统默认的ProxySelector会检测各种系统属性和URL协议,然后决定怎样连接不同的主机。

SocketFactory用来创建socket,这里也使用的默认的

OkHostnameVerifier、Authenticator和CertificatePinner是认证相关的

然后最重要的是创建了一个ConnectionPool连接池

  public ConnectionPool() {    this(5, 5, TimeUnit.MINUTES);  }
<pre name="code" class="java">  public ConnectionPool(int maxIdleConnections, long keepAliveDuration, TimeUnit timeUnit) {    this.maxIdleConnections = maxIdleConnections;    this.keepAliveDurationNs = timeUnit.toNanos(keepAliveDuration);    // Put a floor on the keep alive duration, otherwise cleanup will spin loop.    if (keepAliveDuration <= 0) {      throw new IllegalArgumentException("keepAliveDuration <= 0: " + keepAliveDuration);    }  }


设置最大空闲连接数,保持连接的时间

回到前面的初始化函数,最后是设置Dns,以及连接超时,读超时,写超时时间

Builder创建完成之后会用他初始化OkHttpClient

private OkHttpClient(Builder builder) {    this.dispatcher = builder.dispatcher;    this.proxy = builder.proxy;    this.protocols = builder.protocols;    this.connectionSpecs = builder.connectionSpecs;    this.interceptors = Util.immutableList(builder.interceptors);    this.networkInterceptors = Util.immutableList(builder.networkInterceptors);    this.proxySelector = builder.proxySelector;    this.cookieJar = builder.cookieJar;    this.cache = builder.cache;    this.internalCache = builder.internalCache;    this.socketFactory = builder.socketFactory;    boolean isTLS = false;    for (ConnectionSpec spec : connectionSpecs) {      isTLS = isTLS || spec.isTls();    }    if (builder.sslSocketFactory != null || !isTLS) {      this.sslSocketFactory = builder.sslSocketFactory;      this.certificateChainCleaner = builder.certificateChainCleaner;    } else {      X509TrustManager trustManager = systemDefaultTrustManager();      this.sslSocketFactory = systemDefaultSslSocketFactory(trustManager);      this.certificateChainCleaner = CertificateChainCleaner.get(trustManager);    }    this.hostnameVerifier = builder.hostnameVerifier;    this.certificatePinner = builder.certificatePinner.withCertificateChainCleaner(        certificateChainCleaner);    this.proxyAuthenticator = builder.proxyAuthenticator;    this.authenticator = builder.authenticator;    this.connectionPool = builder.connectionPool;    this.dns = builder.dns;    this.followSslRedirects = builder.followSslRedirects;    this.followRedirects = builder.followRedirects;    this.retryOnConnectionFailure = builder.retryOnConnectionFailure;    this.connectTimeout = builder.connectTimeout;    this.readTimeout = builder.readTimeout;    this.writeTimeout = builder.writeTimeout;  }

这样OkHttpClient就创建完成了。



0 0
原创粉丝点击