OKHttp网络框架源码解析(一)okHttp框架同步异步请求流程和源码分析

首先看下简单使用

1.github官网:https://square.github.io/okhttp/
2.添加依赖:compile ‘com.squareup.okhttp3:okhttp:3.10.0’
3.同步请求

 OkHttpClient okHttpClient=new OkHttpClient.Builder().readTimeout(5000, TimeUnit.SECONDS).build();
    public void synRequest(){
        Request request=new Request.Builder().url("http://www.baidu.com")
                .get()
                .build();
        Call call = okHttpClient.newCall(request);
        try {
            Response response = call.execute();
            System.out.println(response.body().string());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

同步问题:发送请求请求后,就会进入阻塞,直到接受到响应

4.异步请求

 public void asyRequest() {
        Request request = new Request.Builder().url("http://www.baidu.com")

                .get()
                .build();
        Call call = okHttpClient.newCall(request);

          call.enqueue(new Callback() {
           //onFailure和onResponse都是运行在工作线程也就是子线程中
              @Override
              public void onFailure(Call call, IOException e) {

              }

              @Override
              public void onResponse(Call call, Response response) throws IOException {
                  System.out.println(response.body().string());
              }
          });
    }

源码分析

okHttp框架同步请求流程和源码分析

1.OkHttpClient.Builder()方法中需要留意两个参数,builder方法主要用来放置参数

  • dispatcher = new Dispatcher();事件分发器,主要判断异步是直接执行还是缓存执行
  • connectionPool = new ConnectionPool();连接池

2.Request.Builder()方法源码分析

public Builder() {
       //请求方法,默认是get请求
      this.method = "GET";
      //头部信息
      this.headers = new Headers.Builder();
    }

   //builder方法
   public Request build() {
      if (url == null) throw new IllegalStateException("url == null");
      return new Request(this);
    }
   //new Request,设置参数为builder设置的参数
  Request(Builder builder) {
    this.url = builder.url;
    this.method = builder.method;
    this.headers = builder.headers.build();
    this.body = builder.body;
    this.tag = builder.tag != null ? builder.tag : this;
  }

3.Call call = okHttpClient.newCall(request);源码分析

 @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方法
    RealCall call = new RealCall(client, originalRequest, forWebSocket);
    call.eventListener = client.eventListenerFactory().create(call);
    return call;
  }

 private RealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {
    this.client = client;
    this.originalRequest = originalRequest;
    this.forWebSocket = forWebSocket;
    this.retryAndFollowUpInterceptor = new RetryAndFollowUpInterceptor(client, forWebSocket);
  }
//将我们设置参数给RealCall
private RealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {
    this.client = client;
    this.originalRequest = originalRequest;
    this.forWebSocket = forWebSocket;
    this.retryAndFollowUpInterceptor = new RetryAndFollowUpInterceptor(client, forWebSocket);
  }

4. Response response = call.execute();源码分析

//会调用RealCall中的execute方法
Response execute() throws IOException;

@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的目的就是将请求添加到同步请求队列中,自己看源码就知道了
      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);
    }
  }

client.dispatcher().finished(this);源码分析

  void finished(RealCall call) {
     //同步最后一个参数为false,异步最后一个参数为true
    finished(runningSyncCalls, call, false);
  }

  private <T> void finished(Deque<T> calls, T call, boolean promoteCalls) {
    int runningCallsCount;
    Runnable idleCallback;
    synchronized (this) {
      if (!calls.remove(call)) throw new AssertionError("Call wasn't in-flight!");
      //因为是false所以下面方法不会执行
      if (promoteCalls) promoteCalls();
      //正在运行的数量=正在运行数量的同步的大小+正在运行异步数量的大小
      runningCallsCount = runningCallsCount();
      idleCallback = this.idleCallback;
    }

    if (runningCallsCount == 0 && idleCallback != null) {
      idleCallback.run();
    }
  }

至此同步请求源码分析结束

okHttp框架异步请求流程和源码分析

前三步和上面一样就不阐述了
call.enqueue源码分析

//RealCall中实现
  void enqueue(Callback responseCallback);

 @Override public void enqueue(Callback responseCallback) {
    synchronized (this) {
     //是否已经执行过,执行过返回异常
      if (executed) throw new IllegalStateException("Already Executed");
      executed = true;
    }
    captureCallStackTrace();
    //之前同步的时候说了
    eventListener.callStart(this);
    //AsyncCall继承于NamedRunnable,而NamedRunnable实际继承与Runnable
    client.dispatcher().enqueue(new AsyncCall(responseCallback));
  }

  synchronized void enqueue(AsyncCall call) {
   //正在运行的大小小于最大请求  maxRequests =64
    if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {
    //将请求添加到正在运行的请求队列中
      runningAsyncCalls.add(call);
      //线程池去执行
      executorService().execute(call);
    } else {
    //添加到已经准备的线程中
      readyAsyncCalls.add(call);
    }
  }

executorService()

  public synchronized ExecutorService executorService() {
    if (executorService == null) {
    //第一个参数核心线程数量,这里设置为0,目的是当空闲一段时间,将所有线程销毁
    //Integer.MAX_VALUE为整形的最大值,不会印象性能,原因是OKHttp中设置了maxRequests=64
    //第三个参数代表我们当前线程数大于核心线程数量时,最大空闲存活时间是60秒
      executorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS,
          new SynchronousQueue<Runnable>(), Util.threadFactory("OkHttp Dispatcher", false));
    }
    return executorService;
  }

executorService().execute(call);

//首先AsyncCall分析
final class AsyncCall extends NamedRunnable {}//看下NamedRunnalbe
//继承于runnable,也就是开了工作线程
public abstract class NamedRunnable implements Runnable {
  @Override public final void run() {
    String oldName = Thread.currentThread().getName();
    Thread.currentThread().setName(name);
    try {
      execute();
    } finally {
      Thread.currentThread().setName(oldName);
    }
  }
  //看下execute是哪个方法执行了 ,实际是RealCall执行了
  protected abstract void execute();
}

execute

 @Override protected void execute() {
      boolean signalledCallback = false;
      try {
        //getResponseWithInterceptorChain接下来分析
        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) {
      } finally {
        client.dispatcher().finished(this);
      }
    }
  }

  void finished(AsyncCall call) {
  //之前同步也调用改方法,但是最后一个参数传的是false
    finished(runningAsyncCalls, call, true);
  }

 private <T> void finished(Deque<T> calls, T call, boolean promoteCalls) {
    int runningCallsCount;
    Runnable idleCallback;
    synchronized (this) {
    //正在运行的请求队列中移除改请求
      if (!calls.remove(call)) throw new AssertionError("Call wasn't in-flight!");
        //从准备好的请求队列中取出数据添加到正在运行的请求队列中
      if (promoteCalls) promoteCalls();
      runningCallsCount = runningCallsCount();
      idleCallback = this.idleCallback;
    }

    if (runningCallsCount == 0 && idleCallback != null) {
      idleCallback.run();
    }
  }

promoteCalls:源码

 private void promoteCalls() {
    if (runningAsyncCalls.size() >= maxRequests) return; // Already running max capacity.
    if (readyAsyncCalls.isEmpty()) return; // No ready calls to promote.
     //遍历取出缓存中的数据
    for (Iterator<AsyncCall> i = readyAsyncCalls.iterator(); i.hasNext(); ) {
      AsyncCall call = i.next();
      if (runningCallsForHost(call) < maxRequestsPerHost) {
        //从缓存的队列中移除
        i.remove();
        //将刚才从缓存队列获得的请求添加到当前正在运行的队列中
        runningAsyncCalls.add(call);
        executorService().execute(call);
      }

      if (runningAsyncCalls.size() >= maxRequests) return; // Reached max capacity.
    }
  }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值