OkHttp3源码(一) ------ OkHttpClient

关于OkHttp3之前用的时候没有考虑过它的内部实现过程,今天在这里整理记录一下。
接下来我会将OkHttpClient类中常用的方法,内部类、字段加上自己理解的注释,通过看注释了解OkHttpClient的主要用途。

public class OkHttpClient implements Cloneable, Call.Factory, WebSocket.Factory {
    //OkHttp默认支持的协议Http1.1和OkHttp2
    static final List<Protocol> DEFAULT_PROTOCOLS = Util.immutableList(
            Protocol.HTTP_2, Protocol.HTTP_1_1);
    //默认的连接规则
    static final List<ConnectionSpec> DEFAULT_CONNECTION_SPECS = Util.immutableList(
            ConnectionSpec.MODERN_TLS, ConnectionSpec.CLEARTEXT);
    static {
        /*这个类对象的主要用途是操作连接池类,这样做保证了唯一性。*/
        Internal.instance = new Internal() {
            //设置OkHttpClient的内部缓存
            @Override public void setCache(OkHttpClient.Builder builder, InternalCache internalCache) {
                builder.setInternalCache(internalCache);
            }
            //连接池判断指定的连接是否空闲,如果空闲则清除指定连接,否则扫描连接池有无到期的空闲连接。
            @Override public boolean connectionBecameIdle(
                    ConnectionPool pool, RealConnection connection) {
                return pool.connectionBecameIdle(connection);
            }
            //获得连接池中和本次连接的URL相同的连接
            @Override public RealConnection get(ConnectionPool pool, Address address,
                                                StreamAllocation streamAllocation, Route route) {
                return pool.get(address, streamAllocation, route);
            }
            //比较两个地址的非主机部分(DNS、协议、连接规则等)
            @Override public boolean equalsNonHost(Address a, Address b) {
                return a.equalsNonHost(b);
            }
            //主要针对HTTP2的多路复用,复用连接池中是Http2的连接并且要符合address要求。
            @Override public Socket deduplicate(
                    ConnectionPool pool, Address address, StreamAllocation streamAllocation) {
                return pool.deduplicate(address, streamAllocation);
            }
            //将连接放入连接池,并扫描连接池有无到期的空闲连接
            @Override public void put(ConnectionPool pool, RealConnection connection) {
                pool.put(connection);
            }
            //获得相应码
            @Override public int code(Response.Builder responseBuilder) {
                return responseBuilder.code;
            }
            //构造HttpUrl,构造方式是检查URL有无语法错误,有则抛出异常,没有则肢解URL给HttpUrl。
            @Override public HttpUrl getHttpUrlChecked(String url)
                    throws MalformedURLException, UnknownHostException {
                return HttpUrl.getChecked(url);
            }
            //获得连接上的流。
            @Override public StreamAllocation streamAllocation(Call call) {
                return ((RealCall) call).streamAllocation();
            }
        };
    }

    //使用默认的Builder构建自身
    public OkHttpClient() {
        this(new Builder());
    }
    //使用自定义的Builder构建自身,这里面就是将Builder的参数传递给自身
    OkHttpClient(Builder builder) {
        /*
        * 。。。。。。。。。。。。。
        * */
    }

    /** Default connect timeout (in milliseconds). */
    public int connectTimeoutMillis() {
        return connectTimeout;
    }
    /** Default read timeout (in milliseconds). */
    public int readTimeoutMillis() {
        return readTimeout;
    }
    /** Default write timeout (in milliseconds). */
    public int writeTimeoutMillis() {
        return writeTimeout;
    }
    //获得缓存类对象,操作缓存
    public Cache cache() {
        return cache;
    }
    //获得缓存类内部的缓存类对象,其实就是对Cache类对象的操作
    InternalCache internalCache() {
        return cache != null ? cache.internalCache : internalCache;
    }
    //获得DNS(域名反转)
    public Dns dns() {
        return dns;
    }
    //获得连接池
    public ConnectionPool connectionPool() {
        return connectionPool;
    }
    //接下来是否重定向
    public boolean followRedirects() {
        return followRedirects;
    }
    //是否禁止了重连接
    public boolean retryOnConnectionFailure() {
        return retryOnConnectionFailure;
    }
    //获得分发器,分发器类后面会分析
    public Dispatcher dispatcher() {
        return dispatcher;
    }
    //获得网络连接协议
    public List<Protocol> protocols() {
        return protocols;
    }
    //获得连接规则
    public List<ConnectionSpec> connectionSpecs() {
        return connectionSpecs;
    }
    //获得普通的拦截器,这是最先执行的拦截器
    public List<Interceptor> interceptors() {
        return interceptors;
    }
    //获得所有的网络拦截器,这个实在连接服务器后开始执行的
    public List<Interceptor> networkInterceptors() {
        return networkInterceptors;
    }
    //获得网络开始连接及结束连接过程的监听
     EventListener.Factory eventListenerFactory() {
        return eventListenerFactory;
    }
    //实例化事件,这个事件持有请求(request)和客户端(OkHttpClient)
    @Override public Call newCall(Request request) {
        return new RealCall(this, request, false /* for web socket */);
    }
    //通过自身的参数去构建Builder
    public Builder newBuilder() {
        return new Builder(this);
    }


    /**
     * 接下来就是Builder设计模式
     * OkHttp用的比较多的设计模式
     * 对Builder模式不了解的,先去了解下。这里概括一下Builder模式:类的某些字段无法通过自身去赋值,需要委托给其他类去赋值。
     */
    public static final class Builder {
        //使用Builder默认的参数构建Builder
        public Builder() {
            dispatcher = new Dispatcher();
            protocols = DEFAULT_PROTOCOLS;
            connectionSpecs = DEFAULT_CONNECTION_SPECS;
            eventListenerFactory = EventListener.factory(EventListener.NONE);
            connectionPool = new ConnectionPool();
            dns = Dns.SYSTEM;
            followRedirects = true;
            retryOnConnectionFailure = true;
            connectTimeout = 10_000;
            readTimeout = 10_000;
            writeTimeout = 10_000;
        }
        //使用okHttpClient的参数构建Builder,这里面就是将okHttpClient的参数传递给Builder
        Builder(OkHttpClient okHttpClient) {
            /*
            * 。。。。。。。。
            * */
        }
        //设置连接超时时间
        public Builder connectTimeout(long timeout, TimeUnit unit) {
            connectTimeout = checkDuration("timeout", timeout, unit);
            return this;
        }
        //设置读取数据的超时时间
        public Builder readTimeout(long timeout, TimeUnit unit) {
            readTimeout = checkDuration("timeout", timeout, unit);
            return this;
        }
        //设置写入数据的超时时间
        public Builder writeTimeout(long timeout, TimeUnit unit) {
            writeTimeout = checkDuration("timeout", timeout, unit);
            return this;
        }
        //检查超时时间是否为合法的
        private static int checkDuration(String name, long duration, TimeUnit unit) {
            if (duration < 0) throw new IllegalArgumentException(name + " < 0");
            if (unit == null) throw new NullPointerException("unit == null");
            long millis = unit.toMillis(duration);
            if (millis > Integer.MAX_VALUE) throw new IllegalArgumentException(name + " too large.");
            if (millis == 0 && duration > 0) throw new IllegalArgumentException(name + " too small.");
            return (int) millis;
        }
        //设置Cache类的内部缓存类,并将cache置空
        void setInternalCache(InternalCache internalCache) {
            this.internalCache = internalCache;
            this.cache = null;
        }
        //设置cache,并将Cache类的内部缓存类的引用置空
        public Builder cache(Cache cache) {
            this.cache = cache;
            this.internalCache = null;
            return this;
        }
        //设置DNS
        public Builder dns(Dns dns) {
            if (dns == null) throw new NullPointerException("dns == null");
            this.dns = dns;
            return this;
        }
        //设置自定义的连接池
        public Builder connectionPool(ConnectionPool connectionPool) {
            if (connectionPool == null) throw new NullPointerException("connectionPool == null");
            this.connectionPool = connectionPool;
            return this;
        }
        //设置是否接受重定向
        public Builder followRedirects(boolean followRedirects) {
            this.followRedirects = followRedirects;
            return this;
        }
        //设置是否禁止重连接
        public Builder retryOnConnectionFailure(boolean retryOnConnectionFailure) {
            this.retryOnConnectionFailure = retryOnConnectionFailure;
            return this;
        }
        //设置自定义的分发器
        public Builder dispatcher(Dispatcher dispatcher) {
            if (dispatcher == null) throw new IllegalArgumentException("dispatcher == null");
            this.dispatcher = dispatcher;
            return this;
        }
        //设置自定义的协议,自定义的协议不能包括HTTP1.0和null,由此可知Okhttp不支持Http1.0协议
        public Builder protocols(List<Protocol> protocols) {
            // Create a private copy of the list.
            protocols = new ArrayList<>(protocols);

            // Validate that the list has everything we require and nothing we forbid.
            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");
            }
            if (protocols.contains(Protocol.SPDY_3)) {
                protocols.remove(Protocol.SPDY_3);
            }
            this.protocols = Collections.unmodifiableList(protocols);
            return this;
        }
        //设置自定义的连接规则
        public Builder connectionSpecs(List<ConnectionSpec> connectionSpecs) {
            this.connectionSpecs = Util.immutableList(connectionSpecs);
            return this;
        }
        //获得自定义的普通拦截器
        public List<Interceptor> interceptors() {
            return interceptors;
        }
        //设置自定义的普通拦截器
        public Builder addInterceptor(Interceptor interceptor) {
            interceptors.add(interceptor);
            return this;
        }
        //获得自定义的网络拦截器
        public List<Interceptor> networkInterceptors() {
            return networkInterceptors;
        }
        //设置自定义的网络拦截器
        public Builder addNetworkInterceptor(Interceptor interceptor) {
            networkInterceptors.add(interceptor);
            return this;
        }
        //设置网络开始及结束连接的监听器
         Builder eventListener(EventListener eventListener) {
            if (eventListener == null) throw new NullPointerException("eventListener == null");
            this.eventListenerFactory = EventListener.factory(eventListener);
            return this;
        }
        //通过构建好的Builder去构建OkHttpClient,其实就是将Builder设置的字段传递给OkHttpClient
        public OkHttpClient build() {
            return new OkHttpClient(this);
        }
    }

OkHttpClient的主要用途:
通过源码我们可以看到OkHttpClient起到的作用主要是配置网络连接过程中你需要用到的东西。
这些东西包括:
超时时间(XxxTimeout)、
拦截器(interceptors)、
监听器(EventListener)、
自定义分发器(Dispatcher)、
是否重新连接(retryOnConnectionFailure)、
自定义连接池(ConnectionPool)等

©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页