美文网首页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