OkHttp3.6.0源码解析

2018-07-06  本文已影响56人  Wocus

前言

OkHttp是一个非常流行的框架,已经被谷歌加入开源库中,Retrofit目前也是采用OkHttp实现的,此文章纯属个人笔记。
github地址 https://github.com/square/okhttp

基本使用

        val httpClient=OkHttpClient()
        val request=Request.Builder().url("www.baidu.com").build()
        //同步请求
        val response= httpClient.newCall(request).execute()
        if(response.isSuccessful)
            "成功"
        else
            "失败"
//异步请求
httpClient.newCall(request).enqueue(object :Callback{
            override fun onFailure(call: Call?, e: IOException?) {

            }

            override fun onResponse(call: Call?, response: Response?) {

            }
        })

1.实例化OkHttpClient()
2.初始化请求头request
3.带上请求头发送请求,回掉

源码解析

一,HttpClient()
 public OkHttpClient() {
    this(new Builder());
  }
public Builder() {
      dispatcher = new Dispatcher();
      protocols = DEFAULT_PROTOCOLS;
      connectionSpecs = DEFAULT_CONNECTION_SPECS;
      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;
    }

初始化OkhttpClient里面初始化了很多值

二,Request


  final HttpUrl url;//请求地址
  final String method;//请求方式
  final Headers headers;//请求头
  final RequestBody body;//请求内容
  final Object tag;

  public Builder() {
      this.method = "GET";
      this.headers = new Headers.Builder();
    }


 public Builder url(String url) {
      if (url == null) throw new NullPointerException("url == null");

      // Silently replace web socket URLs with HTTP URLs.
      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);
      }

      HttpUrl parsed = HttpUrl.parse(url);
      if (parsed == null) throw new IllegalArgumentException("unexpected url: " + url);
      return url(parsed);
    }

public Request build() {
      if (url == null) throw new IllegalStateException("url == null");
      return new Request(this);
    }

public Builder get() {
      return method("GET", null);
    }

public Builder post(RequestBody body) {
      return method("POST", body);
    }

此代码非常的清楚
1.Builder()默认请求get,初始化请求头
2.url(string)url赋值,在里面并且判断url是否为空拼接完整htpp请求网址,最后判断此http请求是否可用并返回
3.build()初始化完成

三,Response


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

 @Override public Response execute() throws IOException {
    synchronized (this) {
      if (executed) throw new IllegalStateException("Already Executed");
      executed = true;
    }
    captureCallStackTrace();
    try {
      client.dispatcher().executed(this);
      Response result = getResponseWithInterceptorChain();
      if (result == null) throw new IOException("Canceled");
      return result;
    } finally {
      client.dispatcher().finished(this);
    }
  }

@Override public void enqueue(Callback responseCallback) {
    synchronized (this) {
      if (executed) throw new IllegalStateException("Already Executed");
      executed = true;
    }
    captureCallStackTrace();
    client.dispatcher().enqueue(new AsyncCall(responseCallback));
  }

如果executed等于true,说明已经被执行,如果再次调用执行就抛出异常。这说明了一个Call只能被执行。
可以看到同步请求生成的是RealCall对象,而异步请求生成的是AsyncCall对象。AsyncCall说到底其实就是Runnable的子类。
接着上面继续分析,如果可以执行,则对当前请求添加监听器等操作,然后将请求Call对象放入调度器Dispatcher中。最后由拦截器链中的各个拦截器来对该请求进行处理,返回最终的Response。

上一篇下一篇

猜你喜欢

热点阅读