OkHttp源码阅读之旅(一)

为什么要学习源码:
     作为一个中级工程师(自我定位),如何提高自己的代码能力是迫在眉睫的需求,阅读源码好处就不多说了,可以提高架构能力,阅读优秀的可以减少很多学习上的弯路。
源码的选择:
     直接阅读Android的源码,对于学习Android的运行机制有好处,但是Android是一个重量级的操作系统,阅读源码只能从点上去逐渐了解某个机制的细节,要完全阅读Android操作系统,几乎是不可能的事情。所以选择学习从Okhttp这个近年来火的一塌糊涂的网络框架开始。


阅读的顺序:
      笔者入行较浅,本博客实际上为不断学习的过程,在学习过程中出现的错误,还望不吝指正。


对于OkHttp的学习,我们从OkHttpClient这个用户最熟悉的类开始向下挖掘。今天先对其做个概览:

public class OkHttpClient
  implements Cloneable
{
// 默认的协议
  private static final List<Protocol> DEFAULT_PROTOCOLS = Util.immutableList(new Protocol[] { Protocol.HTTP_2, Protocol.SPDY_3, Protocol.HTTP_1_1 });
/* 默认的连接规范
1.MODERN_TLS 是连接到最新的HTTPS服务器的安全配置。
2.COMPATIBEL_TLS 是连接到过时的HTTPS服务器的安全配置。
3.CLEARTEXT 是用于http://开头的URL的非安全配置。
*/
private static final List<ConnectionSpec> DEFAULT_CONNECTION_SPECS = Util.immutableList(new ConnectionSpec[] { ConnectionSpec.MODERN_TLS, ConnectionSpec.COMPATIBLE_TLS, ConnectionSpec.CLEARTEXT });
 //默认SSLSocket工厂
 private static SSLSocketFactory defaultSslSocketFactory;
//路由服务器
  private final RouteDatabase routeDatabase;
//分发器
  private Dispatcher dispatcher;
//代理
  private Proxy proxy;
//协议列表
  private List<Protocol> protocols;
//连接规范
  private List<ConnectionSpec> connectionSpecs;
  
  static
  { //见Internal类
    Internal.instance = new Internal()
    {
      public void addLenient(Headers.Builder builder, String line)
      {
        builder.addLenient(line);
      }
      
      public void addLenient(Headers.Builder builder, String name, String value)
      {
        builder.addLenient(name, value);
      }
      
      public void setCache(OkHttpClient client, InternalCache internalCache)
      {
        client.setInternalCache(internalCache);
      }
      
      public InternalCache internalCache(OkHttpClient client)
      {
        return client.internalCache();
      }
      
      public boolean connectionBecameIdle(ConnectionPool pool, RealConnection connection)
      {
        return pool.connectionBecameIdle(connection);
      }
      
      public RealConnection get(ConnectionPool pool, Address address, StreamAllocation streamAllocation)
      {
        return pool.get(address, streamAllocation);
      }
      
      public void put(ConnectionPool pool, RealConnection connection)
      {
        pool.put(connection);
      }
      
      public RouteDatabase routeDatabase(ConnectionPool connectionPool)
      {
        return connectionPool.routeDatabase;
      }
      
      public void callEnqueue(Call call, Callback responseCallback, boolean forWebSocket)
      {
        call.enqueue(responseCallback, forWebSocket);
      }
      
      public StreamAllocation callEngineGetStreamAllocation(Call call)
      {
        return call.engine.streamAllocation;
      }
      
      public void apply(ConnectionSpec tlsConfiguration, SSLSocket sslSocket, boolean isFallback)
      {
        tlsConfiguration.apply(sslSocket, isFallback);
      }
      
      public HttpUrl getHttpUrlChecked(String url)
        throws MalformedURLException, UnknownHostException
      {
        return HttpUrl.getChecked(url);
      }
    };
  }
  //拦截机
  private final List<Interceptor> interceptors = new ArrayList();
  //网络拦截机
  private final List<Interceptor> networkInterceptors = new ArrayList();
  //代理选择器
  private ProxySelector proxySelector;
  //CookieHandler
  private CookieHandler cookieHandler;
  //InternalCache
  private InternalCache internalCache;
  //缓存
  private Cache cache;
   //socket工厂
  private SocketFactory socketFactory;
    //sslSocket工厂
  private SSLSocketFactory sslSocketFactory;
    //主机名验证着
  private HostnameVerifier hostnameVerifier;
   //证书
  private CertificatePinner certificatePinner;
   //作者
  private Authenticator authenticator;
   //连接池
  private ConnectionPool connectionPool;
   //DNS
  private Dns dns;
   //跟随ssl更改
  private boolean followSslRedirects = true;
  //跟随更改
  private boolean followRedirects = true;
  //重连失败
  private boolean retryOnConnectionFailure = true;
  //连接超时时间
  private int connectTimeout = 10000;
   //读取超时时间
  private int readTimeout = 10000;
 //写超时时间
  private int writeTimeout = 10000;
  
  public OkHttpClient()
  {
	//新建路由数据库
    this.routeDatabase = new RouteDatabase();
       //新建分发器
    this.dispatcher = new Dispatcher();
  }
  
  private OkHttpClient(OkHttpClient okHttpClient)
  {
    this.routeDatabase = okHttpClient.routeDatabase;
    this.dispatcher = okHttpClient.dispatcher;
    this.proxy = okHttpClient.proxy;
    this.protocols = okHttpClient.protocols;
    this.connectionSpecs = okHttpClient.connectionSpecs;
    this.interceptors.addAll(okHttpClient.interceptors);
    this.networkInterceptors.addAll(okHttpClient.networkInterceptors);
    this.proxySelector = okHttpClient.proxySelector;
    this.cookieHandler = okHttpClient.cookieHandler;
    this.cache = okHttpClient.cache;
    this.internalCache = (this.cache != null ? this.cache.internalCache : okHttpClient.internalCache);
    this.socketFactory = okHttpClient.socketFactory;
    this.sslSocketFactory = okHttpClient.sslSocketFactory;
    this.hostnameVerifier = okHttpClient.hostnameVerifier;
    this.certificatePinner = okHttpClient.certificatePinner;
    this.authenticator = okHttpClient.authenticator;
    this.connectionPool = okHttpClient.connectionPool;
    this.dns = okHttpClient.dns;
    this.followSslRedirects = okHttpClient.followSslRedirects;
    this.followRedirects = okHttpClient.followRedirects;
    this.retryOnConnectionFailure = okHttpClient.retryOnConnectionFailure;
    this.connectTimeout = okHttpClient.connectTimeout;
    this.readTimeout = okHttpClient.readTimeout;
    this.writeTimeout = okHttpClient.writeTimeout;
  }
  
  public void setConnectTimeout(long timeout, TimeUnit unit)
  {
    if (timeout < 0L) {
      throw new IllegalArgumentException("timeout < 0");
    }
    if (unit == null) {
      throw new IllegalArgumentException("unit == null");
    }
    long millis = unit.toMillis(timeout);
    if (millis > 2147483647L) {
      throw new IllegalArgumentException("Timeout too large.");
    }
    if ((millis == 0L) && (timeout > 0L)) {
      throw new IllegalArgumentException("Timeout too small.");
    }
    this.connectTimeout = ((int)millis);
  }
  
  public int getConnectTimeout()
  {
    return this.connectTimeout;
  }
  
  public void setReadTimeout(long timeout, TimeUnit unit)
  {
    if (timeout < 0L) {
      throw new IllegalArgumentException("timeout < 0");
    }
    if (unit == null) {
      throw new IllegalArgumentException("unit == null");
    }
    long millis = unit.toMillis(timeout);
    if (millis > 2147483647L) {
      throw new IllegalArgumentException("Timeout too large.");
    }
    if ((millis == 0L) && (timeout > 0L)) {
      throw new IllegalArgumentException("Timeout too small.");
    }
    this.readTimeout = ((int)millis);
  }
  
  public int getReadTimeout()
  {
    return this.readTimeout;
  }
  
  public void setWriteTimeout(long timeout, TimeUnit unit)
  {
    if (timeout < 0L) {
      throw new IllegalArgumentException("timeout < 0");
    }
    if (unit == null) {
      throw new IllegalArgumentException("unit == null");
    }
    long millis = unit.toMillis(timeout);
    if (millis > 2147483647L) {
      throw new IllegalArgumentException("Timeout too large.");
    }
    if ((millis == 0L) && (timeout > 0L)) {
      throw new IllegalArgumentException("Timeout too small.");
    }
    this.writeTimeout = ((int)millis);
  }
  
  public int getWriteTimeout()
  {
    return this.writeTimeout;
  }
  
  public OkHttpClient setProxy(Proxy proxy)
  {
    this.proxy = proxy;
    return this;
  }
  
  public Proxy getProxy()
  {
    return this.proxy;
  }
  
  public OkHttpClient setProxySelector(ProxySelector proxySelector)
  {
    this.proxySelector = proxySelector;
    return this;
  }
  
  public ProxySelector getProxySelector()
  {
    return this.proxySelector;
  }
  
  public OkHttpClient setCookieHandler(CookieHandler cookieHandler)
  {
    this.cookieHandler = cookieHandler;
    return this;
  }
  
  public CookieHandler getCookieHandler()
  {
    return this.cookieHandler;
  }
  
  void setInternalCache(InternalCache internalCache)
  {
    this.internalCache = internalCache;
    this.cache = null;
  }
  
  InternalCache internalCache()
  {
    return this.internalCache;
  }
  
  public OkHttpClient setCache(Cache cache)
  {
    this.cache = cache;
    this.internalCache = null;
    return this;
  }
  
  public Cache getCache()
  {
    return this.cache;
  }
  
  public OkHttpClient setDns(Dns dns)
  {
    this.dns = dns;
    return this;
  }
  
  public Dns getDns()
  {
    return this.dns;
  }
  
  public OkHttpClient setSocketFactory(SocketFactory socketFactory)
  {
    this.socketFactory = socketFactory;
    return this;
  }
  
  public SocketFactory getSocketFactory()
  {
    return this.socketFactory;
  }
  
  public OkHttpClient setSslSocketFactory(SSLSocketFactory sslSocketFactory)
  {
    this.sslSocketFactory = sslSocketFactory;
    return this;
  }
  
  public SSLSocketFactory getSslSocketFactory()
  {
    return this.sslSocketFactory;
  }
  
  public OkHttpClient setHostnameVerifier(HostnameVerifier hostnameVerifier)
  {
    this.hostnameVerifier = hostnameVerifier;
    return this;
  }
  
  public HostnameVerifier getHostnameVerifier()
  {
    return this.hostnameVerifier;
  }
  
  public OkHttpClient setCertificatePinner(CertificatePinner certificatePinner)
  {
    this.certificatePinner = certificatePinner;
    return this;
  }
  
  public CertificatePinner getCertificatePinner()
  {
    return this.certificatePinner;
  }
  
  public OkHttpClient setAuthenticator(Authenticator authenticator)
  {
    this.authenticator = authenticator;
    return this;
  }
  
  public Authenticator getAuthenticator()
  {
    return this.authenticator;
  }
  
  public OkHttpClient setConnectionPool(ConnectionPool connectionPool)
  {
    this.connectionPool = connectionPool;
    return this;
  }
  
  public ConnectionPool getConnectionPool()
  {
    return this.connectionPool;
  }
  
  public OkHttpClient setFollowSslRedirects(boolean followProtocolRedirects)
  {
    this.followSslRedirects = followProtocolRedirects;
    return this;
  }
  
  public boolean getFollowSslRedirects()
  {
    return this.followSslRedirects;
  }
  
  public void setFollowRedirects(boolean followRedirects)
  {
    this.followRedirects = followRedirects;
  }
  
  public boolean getFollowRedirects()
  {
    return this.followRedirects;
  }
  
  public void setRetryOnConnectionFailure(boolean retryOnConnectionFailure)
  {
    this.retryOnConnectionFailure = retryOnConnectionFailure;
  }
  
  public boolean getRetryOnConnectionFailure()
  {
    return this.retryOnConnectionFailure;
  }
  
  RouteDatabase routeDatabase()
  {
    return this.routeDatabase;
  }
  
  public OkHttpClient setDispatcher(Dispatcher dispatcher)
  {
    if (dispatcher == null) {
      throw new IllegalArgumentException("dispatcher == null");
    }
    this.dispatcher = dispatcher;
    return this;
  }
  
  public Dispatcher getDispatcher()
  {
    return this.dispatcher;
  }
  
  public OkHttpClient setProtocols(List<Protocol> protocols)
  {
    protocols = Util.immutableList(protocols);
    if (!protocols.contains(Protocol.HTTP_1_1)) {
      throw new IllegalArgumentException("protocols doesn't contain http/1.1: " + protocols);
    }
    if (protocols.contains(Protocol.HTTP_1_0)) {
      throw new IllegalArgumentException("protocols must not contain http/1.0: " + protocols);
    }
    if (protocols.contains(null)) {
      throw new IllegalArgumentException("protocols must not contain null");
    }
    this.protocols = Util.immutableList(protocols);
    return this;
  }
  
  public List<Protocol> getProtocols()
  {
    return this.protocols;
  }
  
  public OkHttpClient setConnectionSpecs(List<ConnectionSpec> connectionSpecs)
  {
    this.connectionSpecs = Util.immutableList(connectionSpecs);
    return this;
  }
  
  public List<ConnectionSpec> getConnectionSpecs()
  {
    return this.connectionSpecs;
  }
  
  public List<Interceptor> interceptors()
  {
    return this.interceptors;
  }
  
  public List<Interceptor> networkInterceptors()
  {
    return this.networkInterceptors;
  }
  
  public Call newCall(Request request)
  {
    return new Call(this, request);
  }
  
  public OkHttpClient cancel(Object tag)
  {
    getDispatcher().cancel(tag);
    return this;
  }
  
  OkHttpClient copyWithDefaults()
  {
    OkHttpClient result = new OkHttpClient(this);
    if (result.proxySelector == null) {
      result.proxySelector = ProxySelector.getDefault();
    }
    if (result.cookieHandler == null) {
      result.cookieHandler = CookieHandler.getDefault();
    }
    if (result.socketFactory == null) {
      result.socketFactory = SocketFactory.getDefault();
    }
    if (result.sslSocketFactory == null) {
      result.sslSocketFactory = getDefaultSSLSocketFactory();
    }
    if (result.hostnameVerifier == null) {
      result.hostnameVerifier = OkHostnameVerifier.INSTANCE;
    }
    if (result.certificatePinner == null) {
      result.certificatePinner = CertificatePinner.DEFAULT;
    }
    if (result.authenticator == null) {
      result.authenticator = AuthenticatorAdapter.INSTANCE;
    }
    if (result.connectionPool == null) {
      result.connectionPool = ConnectionPool.getDefault();
    }
    if (result.protocols == null) {
      result.protocols = DEFAULT_PROTOCOLS;
    }
    if (result.connectionSpecs == null) {
      result.connectionSpecs = DEFAULT_CONNECTION_SPECS;
    }
    if (result.dns == null) {
      result.dns = Dns.SYSTEM;
    }
    return result;
  }
  
  private synchronized SSLSocketFactory getDefaultSSLSocketFactory()
  {
    if (defaultSslSocketFactory == null) {
      try
      {
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, null, null);
        defaultSslSocketFactory = sslContext.getSocketFactory();
      }
      catch (GeneralSecurityException e)
      {
        throw new AssertionError();
      }
    }
    return defaultSslSocketFactory;
  }
  
  public OkHttpClient clone()
  {
    return new OkHttpClient(this);
}

以上贴出了OkhttpClinet这个类的全部源码,这个类中,分析每一个熟悉,从而了解Okhttp的所包含的机制,如SSL、路由、分发器、协议、代理、连接规范等。这之中每一个机制细细分解都是很深的内容,而我们要看的重点,是从OkhttpClient的使用入手,newCall(Request request)方法。该方法返回的类是Call.class。所以下一步我们研究的是Call这个类。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值