美文网首页网络
okHttp源码分析(一)

okHttp源码分析(一)

作者: wervy | 来源:发表于2020-01-02 13:24 被阅读0次

    我们在项目中使用Okhttp的时候,就直接一句代码:

    OkHttpClient client = new OkHttpClient.Builder() .build();
    

    就创建了一个默认网络请求对象。我们来看OkHttpClient内部源码是怎么实现的
    先看描述部分

    /**
     * Factory for {@linkplain Call calls}, which can be used to send HTTP requests and read their
     * responses.
     *
     * <h3>OkHttpClients should be shared</h3>
     *
     * <p>OkHttp performs best when you create a single {@code OkHttpClient} instance and reuse it for
     * all of your HTTP calls. This is because each client holds its own connection pool and thread
     * pools. Reusing connections and threads reduces latency and saves memory. Conversely, creating a
     * client for each request wastes resources on idle pools.
     *
    

    它是一个执行调用Call请求的工厂,用来发送Http请求和读取返回的Response
    OkHttpClients是应该被共享的。

    okHttpClients最好只创建一个单例对象,这样对你的所有Http请求进行复用,这是因为每个client都有自己的连接池和线程池,复用连接池和请求池能减少延迟和节省内存。相反的,对每个请求创建一个client,会浪费空闲池的资源。

    我们现在项目中也是这么处理的,创建一个单例的client对象,处理所有的网络请求

    private HttpClientUtil() {
    
            okHttpBuilder = new OkHttpClient.Builder();
    
            okHttpBuilder.connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS);
            // 添加统一的header
            okHttpBuilder.addInterceptor(new CustomInterceptor());
    
            retrofit = new Retrofit.Builder()
                    .baseUrl(ApiClient.CHANGE_BUSINESS_SERVICE_URL)
                    .client(okHttpBuilder.build())
                    .addConverterFactory(GsonConverterFactory.create())
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                    .build();
    
            apiService = retrofit.create(ApiService.class);
        }
    
        public static HttpClientUtil getInstance() {
            if (instance == null) {
                instance = new HttpClientUtil();
            }
    
            return instance;
        }
    

    继续看描述部分:

    <h3>Shutdown isn't necessary</h3>
     *
     * <p>The threads and connections that are held will be released automatically if they remain idle.
     * But if you are writing a application that needs to aggressively release unused resources you may
     * do so.
     *
     * <p>Shutdown the dispatcher's executor service with {@link ExecutorService#shutdown shutdown()}.
     * This will also cause future calls to the client to be rejected. <pre>   {@code
     *
     *     client.dispatcher().executorService().shutdown();
     * }</pre>
     *
     * <p>Clear the connection pool with {@link ConnectionPool#evictAll() evictAll()}. Note that the
     * connection pool's daemon thread may not exit immediately. <pre>   {@code
     *
     *     client.connectionPool().evictAll();
     * }</pre>
     *
     * <p>If your client has a cache, call {@link Cache#close close()}. Note that it is an error to
     * create calls against a cache that is closed, and doing so will cause the call to crash.
     * <pre>   {@code
     *
     *     client.cache().close();
     * }</pre>
     *
     * <p>OkHttp also uses daemon threads for HTTP/2 connections. These will exit automatically if they
     * remain idle.
    

    关闭不是必须的。
    保持空闲的线程和连接数会自动释放。
    但是如果你要是在写一个应用需要积极的释放未使用的资源,你可以这么做。
    用ExecutorService.shutdown()关闭线程池资源,这样也会导致

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

    用ConnectionPool的evictAll()来清除连接池,需要指出的是,连接池的守护线程不会立即退出

     client.connectionPool().evictAll();
    

    如果你的client有缓存,调用Cache.close()来关闭它,请注意,对已经关闭的缓存创建调用,会导致崩溃

     client.cache().close();
    

    我们接下来OkHttp中最重要的Builder类的Builder方法

    public Builder() {
          dispatcher = new Dispatcher();
          protocols = DEFAULT_PROTOCOLS;
          connectionSpecs = DEFAULT_CONNECTION_SPECS;
          eventListenerFactory = EventListener.factory(EventListener.NONE);
          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;
          pingInterval = 0;
        }
    

    OkHttp3 只使用 Http/1.1或者 Http/2


    image.png

    相关文章

      网友评论

        本文标题:okHttp源码分析(一)

        本文链接:https://www.haomeiwen.com/subject/brunoctx.html