您的当前位置:首页OKhttp源码分析

OKhttp源码分析

2024-12-13 来源:哗拓教育

1、call.eventListener = client.eventListenerFactory().create(call)
建立连接(tcp、tls)

2、client.dispatcher().enqueue(new AsyncCall(responseCallback));

dispatcher(): 处理线程

enqueue(..): 成立的情况下就会去让线程管理去管理线程,让 call 在后台去执行,
如果不成立则会添加到 readyAsyncCalls 队列中,一个待用的队列,随时可能发送请求

AsyncCall:会调用父类run方法中的 execute(),实现在 RealCall 的 execute() 中。

@Override protected void execute() {
      boolean signalledCallback = false;
      try {
        Response response = getResponseWithInterceptorChain();
        if (retryAndFollowUpInterceptor.isCanceled()) {
          signalledCallback = true;
          responseCallback.onFailure(RealCall.this, new IOException("Canceled"));
        } else {
          signalledCallback = true;
          responseCallback.onResponse(RealCall.this, response);
        }
      } catch (IOException e) {
        if (signalledCallback) {
          // Do not signal the callback twice!
          Platform.get().log(INFO, "Callback failure for " + toLoggableString(), e);
        } else {
          eventListener.callFailed(RealCall.this, e);
          responseCallback.onFailure(RealCall.this, e);
        }
      } finally {
        client.dispatcher().finished(this);
      }
    }
  }
 final Dispatcher dispatcher;线程调度管理器

  final @Nullable Proxy proxy;设置代理服务器,如果我们无法访问或访问失败我们的目标服务器,可以交给代理服务器去帮我们访问想要访问的目标服务器

  final List<Protocol> protocols; 所支持的 http 协议版本

  final List<ConnectionSpec> connectionSpecs;配置使用http还是https;包括SSL和TLS版本的选择配置
  final List<Interceptor> interceptors;
  final List<Interceptor> networkInterceptors;
  final EventListener.Factory eventListenerFactory;
  final ProxySelector proxySelector;

  final CookieJar cookieJar;cookie存储器

  final @Nullable Cache cache;http的cache

  final @Nullable InternalCache internalCache;

  final SocketFactory socketFactory;创建tcp端口

  final @Nullable SSLSocketFactory sslSocketFactory;创建SSL端口

  final @Nullable CertificateChainCleaner certificateChainCleaner;整理服务器传输而来的证书

  final HostnameVerifier hostnameVerifier;用于https中,验证对方服务器的host

  final CertificatePinner certificatePinner;做自签名

  final Authenticator proxyAuthenticator;Head中添加Authorizaion,访问权限配置
  final Authenticator authenticator;

  final ConnectionPool connectionPool;连接池

  final Dns dns;
  final boolean followSslRedirects;当遇到http与https互相跳转,是否跳?
  final boolean followRedirects;如果遇到需要跳转的情况下,是否去跳转,比如返回3xx,默认是true
  final boolean retryOnConnectionFailure;请求失败,是否重新连接
  final int connectTimeout;tcp链接时间
  final int readTimeout;下载等待响应时间
  final int writeTimeout;写入响应时间
  final int pingInterval;针对wbsocket的,多久ping一次,客户端发送ping,服务端发送pong
//自签名
public void mySingn() {
        String hostname = 
        CertificatePinner certificatePinner = new CertificatePinner.Builder()
//                .add(hostname, "sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=")
                .add(hostname, "sha256/rZ/xwvaoWYYzhWGtTUCUNO07mHKM82JCfdvWZm1Z7nU=")
                .add(hostname, "sha256/GI75anSEdkuHj05mreE0Sd9jE6dVqUIzzXRHHlZBVbI=")
                .add(hostname, "sha256/r/mIkG3eEpVdm+u/ko/cwxzOMo1bk4TyHIlByibiA5E=")
                .build();
        OkHttpClient client = new OkHttpClient.Builder()
                .certificatePinner(certificatePinner)
                .build();

        Request request = new Request.Builder()
                .url("https://" + hostname)
                .build();
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.i("qqq","onFailure...");

                e.printStackTrace();
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                Log.i("qqq","onSuccess...");

            }
        });
    }

4、分析execute中的getResponseWithInterceptorChain

 Response getResponseWithInterceptorChain() throws IOException {
    // Build a full stack of interceptors.
    List<Interceptor> interceptors = new ArrayList<>();
    interceptors.addAll(client.interceptors());
    interceptors.add(retryAndFollowUpInterceptor);
    interceptors.add(new BridgeInterceptor(client.cookieJar()));
    interceptors.add(new CacheInterceptor(client.internalCache()));
    interceptors.add(new ConnectInterceptor(client));
    if (!forWebSocket) {
      
    }
    interceptors.add(new CallServerInterceptor(forWebSocket));

    Interceptor.Chain chain = new RealInterceptorChain(interceptors, null, null, null, 0,
        originalRequest, this, eventListener, client.connectTimeoutMillis(),
        client.readTimeoutMillis(), client.writeTimeoutMillis());

    return chain.proceed(originalRequest);
  }

作用:将准备好的请求去做网络请求,然后得到响应(response)

image.png

责任链模式

chain.proceed 的流程如上图。

先做请求的前置工作,然后调用proceed()方法,如果proceed()方法返回成功,则会接着去做响应后置工作;在proceed()方法执行过程中,又会去调用下一个拦截器的请求前置工作、proceed()、响应后置工作。。。

client.interceptors():做拦截工作,可以在请求前做一些处理,或者在请求之后做一些处理

retryAndFollowUpInterceptor:用于网络的重试工作

CacheInterceptor:如果已有的cache信息,还在保存期内,那么就直接使用cache中的数据,则不会再去做接下来的网络请求

ConnectInterceptor:在该拦截器中与TCP、HTTPS的TLS来做交互,即建立一个TCP连接或者在TCP的连接上再叠加一个TLS连接。(该拦截器没有后置工作)

CallServerInterceptor:负责向服务器发送请求数据、从服务器读取响应数据(实际网络请求)

image.png

优点:
可以看到,这里首先new了一个Interceptor的ArrayList,然后分别加入了各种各样的Interceptor,所以当我们默认创建okHttpClient时,okHttp默认会给我们实现这些过滤器,每个过滤器执行不同的任务,这个思想太屌了有木有,每个过滤器负责自己的任务,各个过滤器间相互不耦合,高内聚,低耦合,对拓展放开巴拉巴拉等一系列设计思想有木有,这里可以对比一下Volley源码中的思想,Volley的处理是将缓存,网络请求等一系列操作揉在一起写,导致用户对于Volley的修改只能通过修改源码方式,而修改就必须要充分阅读理解volley整个的流程,可能一部分的修改会影响全局的流程,而这里,将不同的职责的过滤器分别单独出来,用户只需要对关注的某一个功能项进行理解,并可以进行扩充修改,一对比,okHttp在这方面的优势立马体现出来了。这里大概先描述一下几个过滤器的功能

显示全文