okHttp源码分析(一)
2020-01-02 本文已影响0人
wervy
我们在项目中使用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
