美文网首页Android
OkHttp源码透析

OkHttp源码透析

作者: 大佬的上半生 | 来源:发表于2019-09-26 16:15 被阅读0次

What?

OkHttp 是一个高效的 HTTP 客户端
它的前世今生,square在使用Android底层HTTP的API不是很好用,内部团队就封装了一套网络请求库命名OkHttp,随着多次迭代修改,摒弃了Apache HttpClient,完全使用HttpURLConnection,Android 6.0,API23.6以后google官方剔除了HttpClient,使用OKHTTP封装的源码。

Why?

正式由于它的强大与优秀,所以被google官方收购使用

优点:

1.HTTP / 2支持允许对同一主机的所有请求共享套接字。
2.连接池减少了请求延迟(如果HTTP / 2不可用)。
3.透明GZIP缩小了下载大小。
4.响应缓存可以完全避免网络重复请求。
5.支持https,http,socket

How?

 OkHttpClient  okHttpClient =new OkHttpClient();
        final Request request      =new Request.Builder().url("https://www.baidu.com").build();
        okhttp3.Call  call         =okHttpClient.newCall(request);
        call.enqueue(new okhttp3.Callback() {
            @Override
            public void onFailure(@NotNull okhttp3.Call call, @NotNull IOException e) {
            }

            @Override
            public void onResponse(@NotNull okhttp3.Call call, @NotNull okhttp3.Response response) throws IOException {
                Log.i("okhttp",response.message());
            }
        });

Code?

1.实例化OkHttpClient两种方式,Builder模式和new,builder设置参数缓存,拦截器,时间等。

OkHttpClient  okHttpClient =new OkHttpClient();
   okHttpClient.newBuilder().readTimeout(Duration.ofMillis(1000)).cache(null).addInterceptor(null);

2.Builder实例化请求Request ,设置请求请求参数,url,请求头等。

final Request request      =new Request.Builder().url("https://www.baidu.com").build();

3.实现Call设置请求请求参数,url,请求头等。

 okhttp3.Call  call         =okHttpClient.newCall(request);
  /** Prepares the [request] to be executed at some point in the future. */
  override fun newCall(request: Request): Call {
    return RealCall.newRealCall(this, request, forWebSocket = false)
  }

4.异步和同步请求回调调用

call.enqueue(new okhttp3.Callback() {
            @Override
            public void onFailure(@NotNull okhttp3.Call call, @NotNull IOException e) {
            }

            @Override
            public void onResponse(@NotNull okhttp3.Call call, @NotNull okhttp3.Response response) throws IOException {
                Log.i("okhttp",response.message());
            }
        });

流程图

image.png

1.OkHttpClient

      //缓存
    public final val cache: okhttp3.Cache? /* compiled code */
    //默认呼叫超时(以毫秒为单位)。默认情况下,完成调用没有超时,但是在调用中有连接,写入和读取操作。
    public final val callTimeoutMillis: kotlin.Int /* compiled code */
    //证书序列
    public final val certificateChainCleaner: okhttp3.internal.tls.CertificateChainCleaner? /* compiled code */
    //用来自签名证书管理
    public final val certificatePinner: okhttp3.CertificatePinner /* compiled code */
    //连接超时事件
    public final val connectTimeoutMillis: kotlin.Int /* compiled code */
    //连接池
    public final val connectionPool: okhttp3.ConnectionPool /* compiled code */
    //连接规格
    public final val connectionSpecs: kotlin.collections.List<okhttp3.ConnectionSpec> /* compiled code */
    //cookie存储器
    public final val cookieJar: okhttp3.CookieJar /* compiled code */
    //线程调度器
    public final val dispatcher: okhttp3.Dispatcher /* compiled code */
    //Dns设置
    public final val dns: okhttp3.Dns /* compiled code */
    //生产统计事件
    public final val eventListenerFactory: okhttp3.EventListener.Factory /* compiled code */
    //设置是否跳转
    public final val followRedirects: kotlin.Boolean /* compiled code */
    //当你访问http是否跳转https
    public final val followSslRedirects: kotlin.Boolean /* compiled code */
    //host验证器
    public final val hostnameVerifier: javax.net.ssl.HostnameVerifier /* compiled code */
    //拦截器
    public final val interceptors: kotlin.collections.List<okhttp3.Interceptor> /* compiled code */
    //返回观察单个网络请求和响应的不可变拦截器列表,这些拦截器必须只调用一次
    public final val networkInterceptors: kotlin.collections.List<okhttp3.Interceptor> /* compiled code */
    //长连接心跳发送时间
    public final val pingIntervalMillis: kotlin.Int /* compiled code */
    //支持http的协议版本
    public final val protocols: kotlin.collections.List<okhttp3.Protocol> /* compiled code */
    //代理服务器
    public final val proxy: java.net.Proxy? /* compiled code */
    //代理授权设置
    public final val proxyAuthenticator: okhttp3.Authenticator /* compiled code */
    //授权设置
    public final val authenticator: okhttp3.Authenticator /* compiled code */
    //读取超时事件
    public final val readTimeoutMillis: kotlin.Int /* compiled code */
    //连接失败,是否重试
    public final val retryOnConnectionFailure: kotlin.Boolean /* compiled code */
    //生产Socket
    public final val socketFactory: javax.net.SocketFactory /* compiled code */
    //生产sslSocket
    public final val sslSocketFactory: javax.net.ssl.SSLSocketFactory /* compiled code */

    //写入超时时间
    public final val writeTimeoutMillis: kotlin.Int /* compiled code */
    //证书设置
    public final val x509TrustManager: javax.net.ssl.X509TrustManager? /* compiled code */

2.Request请求方法体

internal constructor(request: Request) {
      this.url = request.url
      this.method = request.method
      this.body = request.body
      this.tags = if (request.tags.isEmpty()) {
        mutableMapOf()
      } else {
        request.tags.toMutableMap()
      }
      this.headers = request.headers.newBuilder()
    }

3.RealCall

 //同步请求
        override fun execute(): Response {
            synchronized(this) {
                check(!executed) { "Already Executed" }
                executed = true
            }
            transmitter.timeoutEnter()
            transmitter.callStart()
            try {
                client.dispatcher.executed(this)
                return getResponseWithInterceptorChain()
            } finally {
                client.dispatcher.finished(this)
            }
        }
        //异步请求
        override fun enqueue(responseCallback: Callback) {
            synchronized(this) {
                check(!executed) { "Already Executed" }
                executed = true
            }
            transmitter.callStart()
            client.dispatcher.enqueue(AsyncCall(responseCallback))
        }
        //取消
        override fun cancel() {
            transmitter.cancel()
        }

        //异步请求内部方法体
        internal inner class AsyncCall(
        private val responseCallback: Callback
  ) : Runnable {

            override fun run() {
                threadName("OkHttp ${redactedUrl()}") {
                    var signalledCallback = false
                    transmitter.timeoutEnter()
                    try {
                        val response = getResponseWithInterceptorChain()
                        signalledCallback = true
                        responseCallback.onResponse(this@RealCall, response)
                    } catch (e: IOException) {
                        if (signalledCallback) {
                            // Do not signal the callback twice!
                            Platform.get().log(INFO, "Callback failure for ${toLoggableString()}", e)
                        } else {
                            responseCallback.onFailure(this@RealCall, e)
                        }
                    } finally {
                        client.dispatcher.finished(this)
                    }
                }
            }
        }

        @Throws(IOException::class)
        fun getResponseWithInterceptorChain(): Response {
            // Build a full stack of interceptors.
            val interceptors = mutableListOf<Interceptor>()
            interceptors += client.interceptors
            interceptors += RetryAndFollowUpInterceptor(client)
            interceptors += BridgeInterceptor(client.cookieJar)
            interceptors += CacheInterceptor(client.cache)
            interceptors += ConnectInterceptor
            if (!forWebSocket) {
                interceptors += client.networkInterceptors
            }
            interceptors += CallServerInterceptor(forWebSocket)

            val chain = RealInterceptorChain(interceptors, transmitter, null, 0, originalRequest, this,
                    client.connectTimeoutMillis, client.readTimeoutMillis, client.writeTimeoutMillis)

            var calledNoMoreExchanges = false
            try {
                val response = chain.proceed(originalRequest)
                if (transmitter.isCanceled) {
                    response.closeQuietly()
                    throw IOException("Canceled")
                }
                return response
            } catch (e: IOException) {
                calledNoMoreExchanges = true
                throw transmitter.noMoreExchanges(e) as Throwable
            } finally {
                if (!calledNoMoreExchanges) {
                    transmitter.noMoreExchanges(null)
                }
            }
        }

重点!重点!重点!

okhttp核心,采用拦截器成一个任务链,采用责任链模式进行功能解耦,每个interceptor主要任务,事前准备,交给下一个interceptor,事后返回处理,下面看看每个拦截器的任务!

@Throws(IOException::class)
        fun getResponseWithInterceptorChain(): Response {
            // Build a full stack of interceptors.
            val interceptors = mutableListOf<Interceptor>()
            interceptors += client.interceptors
            interceptors += RetryAndFollowUpInterceptor(client)
            interceptors += BridgeInterceptor(client.cookieJar)
            interceptors += CacheInterceptor(client.cache)
            interceptors += ConnectInterceptor
            if (!forWebSocket) {
                interceptors += client.networkInterceptors
            }
            interceptors += CallServerInterceptor(forWebSocket)

            val chain = RealInterceptorChain(interceptors, transmitter, null, 0, originalRequest, this,
                    client.connectTimeoutMillis, client.readTimeoutMillis, client.writeTimeoutMillis)

            var calledNoMoreExchanges = false
            try {
                val response = chain.proceed(originalRequest)
                if (transmitter.isCanceled) {
                    response.closeQuietly()
                    throw IOException("Canceled")
                }
                return response
            } catch (e: IOException) {
                calledNoMoreExchanges = true
                throw transmitter.noMoreExchanges(e) as Throwable
            } finally {
                if (!calledNoMoreExchanges) {
                    transmitter.noMoreExchanges(null)
                }
            }
        }
1.RetryAndFollowUpInterceptor(重试和重定)
2.BridgeInterceptor(连接桥滤器)
3.CacheInterceptor(缓存过滤器)
4.ConnectInterceptor(连接过滤器)
5.CallServerInterceptor(请求服务过滤器)

相关文章

网友评论

    本文标题:OkHttp源码透析

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