OkHttp3源码详解

一、OkHttp源码解析

(1)client = new OkHttpClient():初始化OkHttpClient

  public OkHttpClient() {
    this(new Builder());
  }
    //初始化
    public Builder() {
      dispatcher = new Dispatcher();//调度器
      protocols = DEFAULT_PROTOCOLS;
      connectionSpecs = DEFAULT_CONNECTION_SPECS;
      eventListenerFactory = EventListener.factory(EventListener.NONE);
      proxySelector = ProxySelector.getDefault();
      if (proxySelector == null) {
        proxySelector = new NullProxySelector();
      }
      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;
      callTimeout = 0;
      connectTimeout = 10_000;
      readTimeout = 10_000;
      writeTimeout = 10_000;
      pingInterval = 0;
    }

(2)new Request.Builder().addHeader("token", token).url(url).post(builder.build()).build():网络请求配置参数

    public Builder() {
      this.method = "GET";//默认为get请求
      this.headers = new Headers.Builder();
    }

    //保存头部信息
    public Builder addHeader(String name, String value) {
      headers.add(name, value);
      return this;
    }

    //请求连接
    public Builder url(String url) {
      if (url == null) throw new NullPointerException("url == null");
      if (url.regionMatches(true, 0, "ws:", 0, 3)) {
        url = "http:" + url.substring(3);
      } else if (url.regionMatches(true, 0, "wss:", 0, 4)) {
        url = "https:" + url.substring(4);
      }
      return url(HttpUrl.get(url));
    }

    //设置请求方式
    public Builder post(RequestBody body) {
      return method("POST", body);
    }

    //创建Request实例,赋值设置需求
    public Request build() {
      if (url == null) throw new IllegalStateException("url == null");
      return new Request(this);
    }

  Request(Builder builder) {
    this.url = builder.url;
    this.method = builder.method;
    this.headers = builder.headers.build();
    this.body = builder.body;
    this.tags = Util.immutableMap(builder.tags);
  }

(3)client.newCall(request).enqueue(callback):封装Call对象异步请求

  @Override 
  public Call newCall(Request request) {
    return RealCall.newRealCall(this, request, false /* for web socket */);
  }

  static RealCall newRealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {
    RealCall call = new RealCall(client, originalRequest, forWebSocket);
    call.transmitter = new Transmitter(client, call);
    return call;
  }

  private RealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {
    this.client = client;
    this.originalRequest = originalRequest;
    this.forWebSocket = forWebSocket;
  }

  public Transmitter(OkHttpClient client, Call call) {
    this.client = client;
    this.connectionPool = Internal.instance.realConnectionPool(client.connectionPool());
    this.call = call;
    this.eventListener = client.eventListenerFactory().create(call);
    this.timeout.timeout(client.callTimeoutMillis(), MILLISECONDS);
  }

  @Override 
  public void enqueue(Callback responseCallback) {
    //使用synchronized防止请求重复执行
    synchronized (this) {
      if (executed) throw new IllegalStateException("Already Executed");
      executed = true;
    }
    transmitter.callStart();//调用监听方法
    //AsyncCall继承NamedRunnable抽象类,NamedRunnable实现Runnable,调用执行run方法
    client.dispatcher().enqueue(new AsyncCall(responseCallback));
  }

    AsyncCall(Callback responseCallback) {
      super("OkHttp %s", redactedUrl());
      this.responseCallback = responseCallback;
    }

    @Override 
    protected void execute() {
      boolean signalledCallback = false;
      transmitter.timeoutEnter();
      try {
        //返回数据
        Response response = getResponseWithInterceptorChain();
        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 {
          //失败异常回调
          responseCallback.onFailure(RealCall.this, e);
        }
      } catch (Throwable t) {
        cancel();
        if (!signalledCallback) {
          IOException canceledException = new IOException("canceled due to " + t);
          canceledException.addSuppressed(t);
          //失败异常回调
          responseCallback.onFailure(RealCall.this, canceledException);
        }
        throw t;
      } finally {
        //清除队列
        client.dispatcher().finished(this);
      }
    }
  • OkHttpClient:是OkHttp框架的客户端。用户使用OkHttp进行各种设置,发起各种网络请求都是通过OkHttpClient完成的。每个OkHttpClient内部都维护了属于自己的任务队列,连接池,Cache,拦截器等,所以在使用OkHttp作为网络框架时应该全局共享一个OkHttpClient实例。
  • Call:Call是描述一个实际的访问请求,用户的每一个网络请求都是一个Call实例。Call本身只是一个接口,定义了Call的接口方法,实际执行过程中,OkHttp会为每一个请求创建一个RealCall,每一个RealCall内部有一个AsyncCall,AsyncCall是RealCall的一个内部类并且继承NamedRunnable。
  • Dispatcher:OkHttp的任务队列,其内部维护了一个线程池,当有接收到一个Call时,Dispatcher负责在线程池中找到空闲的线程并执行其execute方法。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容