Okhttp同步请求源码分析

进阶android,OKhttp源码分析——同步请求的源码分析android

OKhttp是咱们常常用到的框架,做为开发者们,咱们不仅仅要学会灵活使用,还要知道他的源码是如何设计的。面试

今天咱们来分析一下OKhttp 同步请求的执行流程和源码分析缓存

so,老样子,咱们先来一张图网络

从上图能够看出,无论是同步请求仍是异步请求,咱们都须要建立一个OKhttpClient对象,用到的是build构造者模式,建立Request对象,而后再OKhttpClient的newCall方法和Request来封装咱们的call对象。建立咱们的实际请求的call对象,从上图能够看到,对于同步请求,咱们调用的是excute方法,异步请求调用的是equeue方法。框架

咱们看一下作简单使用异步

OkHttpClient okHttpClient = new  OkHttpClient.Builder()
                .readTimeout(10, TimeUnit.SECONDS)
                .build();
        Request request = new Request.Builder().url("https://blog.csdn.net/androidstarjack").build();

        Call call = okHttpClient.newCall(request);
        try {
            call.execute();//同步请求
            call.enqueue(new Callback() {//异步请求
                @Override
                public void onFailure(Call call, IOException e) {

                }

                @Override
                public void onResponse(Call call, Response response) throws IOException {

                }
            });
        } catch (IOException e) {
            e.printStackTrace();
        }

咱们先看一下okhttp的build ide

首先咱们经过源码能够看出,okhttp的建立时经过build方法来建立的,其中初始化了一些事情,好比建立一个dispatcher拦截器,和一个链接池,链接池只要是连接状态的保存以及复用。build是要是建立 okhttp是所须要的参数。源码分析

在建立Request建立的时候也是用构造者模式进行建立的,源码以下:ui

Builder(Request request) {
      this.url = request.url;
      this.method = request.method;
      this.body = request.body;
      this.tag = request.tag;
      this.headers = request.headers.newBuilder();
    }

request的build构造里面初始化了一些请求的URL,请求方法哈请求头等请求报文的一些信息。this

Call对象 是经过他的父亲RealCall来完成的。

Call对象持有了Okhttp 和Request两个对象,同时呢还建立了一个缓存拦截器RetryAndFollowUpInterceptor,用于所须要的重定向操做。

经过调用okhttpClient的newCAll来完成CALL的新建,进行相应的操做

紧接着调用execute方法来完成同步请求!

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

//布尔值executed表示一个okhttp请求只能运行执行一次,而后开启捕捉一些错误堆栈信息,点用一个eventListener监听方法,
接卸来是调用分发器的executed方法。这才是重中之重。

...
 client.dispatcher().executed(this);
...

client.dispatcher返回一个分发器。而后经过分发器来执行操做:

在同步请求中,调用executed方法,很简单酒吧这个Call对象添加到队列当中。

Dispatcher的做用主要是维持call请求发给他 的状态,同时维护了一个线程池,开启了网络请求。

从源码中咱们能够看到Dispatcher

这几个请求队列表明着不一样状态下的请求状况。

紧接着经过拦截器链依次调用执行操做。
最后还调用了Finish方法

注意第三个参数,为false,这个方法的主要做用就是移除当前的请求,若是不能移除的话,返回异常,咱们能够注意到,同步请求不须要调用promoteCalls,只有在异步请求的时候才会调用到,这个方法之后咱们在讲。

最后判断,正在将要执行的请求队列集合为0而且闲调用的回调不为null时,调用其run方法。此时,同步方法执行完成。

阅读更多

2018年技术文章汇总

NDK项目实战—高仿360手机助手之卸载监听

(Android)面试题级答案(精选版)

若是对技术开发比较感兴趣,欢迎关注公众号:终端研发部。一块儿交流技术,进阶!

相关文章
相关标签/搜索