OkHttp3 源码阅读

版本是3.14.9

同步请求

OkHttpClient okHttpClient = new OkHttpClient();
Request request = new Request.Builder().url("http://wwww.baidu.com").build();
Call call = okHttpClient.newCall(request);
try {
    Response response = call.execute();
    Log.d(TAG, "Response: " + response.body().string());
} catch (IOException e) {
    e.printStackTrace();
}

同步请求分析

  1. 创建OkHttpClient对象,
public class OkHttpClient implements Cloneable, Call.Factory, WebSocket.Factory {
    public OkHttpClient() {
      this(new Builder());
    }
    public static final class Builder {
        Dispatcher dispatcher;
        public Builder() {
            // 创建Dispatcher对象
            dispatcher = new Dispatcher();
        }
    }
}
  1. 创建Request对象
public final class Request {
    public static class Builder {
        public Builder() {
          this.method = "GET";
          this.headers = new Headers.Builder();
        }
        public Builder url(HttpUrl url) {
          if (url == null) throw new NullPointerException("url == null");
          this.url = url;
          return this;
        }
        public Request build() {
          if (url == null) throw new IllegalStateException("url == null");
          // build()之后返回Request
          return new Request(this);
        }
    }
}
  1. okHttpClient.newCall(request)创建RealCall对象
// 创建RealCall对象, RealCall中的内部类AsyncCall其实是Runnable对象
@Override public Call newCall(Request request) {
  return RealCall.newRealCall(this, request, false /* for web socket */);
}
  1. RealCall.execute()执行请求
// RealCall.java
final class RealCall implements Call {
    // 执行同步请求
    @Override public Response execute() throws IOException {
      synchronized (this) {
        // executed 每个RealCall只能请求一次网络
        if (executed) throw new IllegalStateException("Already Executed");
        executed = true;
      }
      ...
      try {
        // 将RealCall加入到同步请求的队列中
        client.dispatcher().executed(this);
        // 从拦截链获取响应, 异步最终也会走到这个方法,现在再分析异步.
        return getResponseWithInterceptorChain();
      } finally {
        client.dispatcher().finished(this);
      }
    }
}
// Dispatcher.java
public final class Dispatcher {
      // 准备好,还未请求
      private final Deque<AsyncCall> readyAsyncCalls = new ArrayDeque<>();
      // 正在运行的请求
      private final Deque<AsyncCall> runningAsyncCalls = new ArrayDeque<>();
      // 同步请求  
      private final Deque<RealCall> runningSyncCalls = new ArrayDeque<>();
      // 将RealCall对象加入到同步请求队列中
      synchronized void executed(RealCall call) {
        runningSyncCalls.add(call);
      }
}

异步请求

OkHttpClient okHttpClient = new OkHttpClient();
Request request = new Request.Builder().url("http://wwww.baidu.com").build();
Call call = okHttpClient.newCall(request);
call.enqueue(new Callback() {
    @Override
    public void onFailure(Call call, IOException e) {
        Log.d(TAG, "onFailure: ");
    }
    @Override
    public void onResponse(Call call, Response response) throws IOException {
        Log.d(TAG, "Response: " + response.body().string());
    }
});

异步请求分析

  1. OkHttpClient,Request,RealCall对象的创建与同步无异,区别在RealCall.execute()与’RealCall.enqueue()’
final class RealCall implements Call {
    @Override public void enqueue(Callback responseCallback) {
      ... 
      client.dispatcher().enqueue(new AsyncCall(responseCallback));
    }
    // 类型最终为Runnable
    final class AsyncCall extends NamedRunnable {
        void executeOn(ExecutorService executorService) {
          assert (!Thread.holdsLock(client.dispatcher()));
          boolean success = false;
          try {
            // 通过线程池执行当前的AsyncCall,也就是Runnable对象中的run()
            // NamedRunnable类中的run()方法最终调用execute(),该方法具体由AsyncCall实现.
            executorService.execute(this);
            success = true;
          }
          ...
        }
        // run()方法的最终实现
        @Override protected void execute() {
          boolean signalledCallback = false;
          transmitter.timeoutEnter();
          try {
            // 调用拦截器链获取Response
            Response response = getResponseWithInterceptorChain();
            signalledCallback = true;
            // Callback()中的回调方法 
            responseCallback.onResponse(RealCall.this, response);
          } catch (IOException e) {
            ...
          } catch (Throwable t) {
            cancel();
            if (!signalledCallback) {
              ...
              canceledException.addSuppressed(t);
              // Callback()中的回调方法 
              responseCallback.onFailure(RealCall.this, canceledException);
            }
            throw t;
          } finally {
            client.dispatcher().finished(this);
          }
        }
    }

}
public final class Dispatcher {
    private int maxRequests = 64;
    private int maxRequestsPerHost = 5;
    // 准备好,还未请求
    private final Deque<AsyncCall> readyAsyncCalls = new ArrayDeque<>();
    // 正在运行的请求
    private final Deque<AsyncCall> runningAsyncCalls = new ArrayDeque<>();
    // 同步请求  
    private final Deque<RealCall> runningSyncCalls = new ArrayDeque<>();
    // 将RealCall对象加入到同步请求队列中
    synchronized void executed(RealCall call) {
      runningSyncCalls.add(call);
    }

    void enqueue(AsyncCall call) {
      // 将AsyncCall对象加入异步请求准备队列中
      readyAsyncCalls.add(call);
      ...
      // 
      promoteAndExecute();
    }
    
    private boolean promoteAndExecute() {
      assert (!Thread.holdsLock(this));
      // 存储将要执行的异步请求
      List<AsyncCall> executableCalls = new ArrayList<>();
      boolean isRunning;
      synchronized (this) {
        // 等待异步请求队列中遍历
        for (Iterator<AsyncCall> i = readyAsyncCalls.iterator(); i.hasNext(); ) {
          AsyncCall asyncCall = i.next();
          if (runningAsyncCalls.size() >= maxRequests) break; // Max capacity.
          if (asyncCall.callsPerHost().get() >= maxRequestsPerHost) continue; // Host max capacity.
          i.remove();
          asyncCall.callsPerHost().incrementAndGet();
          // 将等待队列中的AsyncCall 加入到正在异步请求的队列中
          executableCalls.add(asyncCall);
          runningAsyncCalls.add(asyncCall);
        }
        isRunning = runningCallsCount() > 0;
      }
      for (int i = 0, size = executableCalls.size(); i < size; i++) {
        // 从集合中取出AsyncCall
        AsyncCall asyncCall = executableCalls.get(i);
        // 调用AsyncCall中的executeOn()方法,executorService()返回一个线程池
        asyncCall.executeOn(executorService());
      }
      return isRunning;
    }
    // 获取一个线程池
    public synchronized ExecutorService executorService() {
      if (executorService == null) {
        // 核心池大小为0,空闲线程最多等待60s收回
        executorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS,
            new SynchronousQueue<>(), Util.threadFactory("OkHttp Dispatcher", false));
      }
      return executorService;
    }
}

getResponseWithInterceptorChain()

final class RealCall implements Call {
    final class AsyncCall extends NamedRunnable {
        
        Response getResponseWithInterceptorChain() throws IOException {
          // Build a full stack of interceptors.
          List<Interceptor> interceptors = new ArrayList<>();
          // OkHttpClient中自己自定义的一些Interceptor
          interceptors.addAll(client.interceptors());
          // 错误、重定向拦截器
          interceptors.add(new RetryAndFollowUpInterceptor(client));
          // 桥接拦截器,桥接应用层与网络层,添加必要的头、  
          interceptors.add(new BridgeInterceptor(client.cookieJar()));
          // 缓存处理,Last-Modified、ETag、DiskLruCache等  
          interceptors.add(new CacheInterceptor(client.internalCache()));
          // 连接拦截器  
          interceptors.add(new ConnectInterceptor(client));
          if (!forWebSocket) {
            // 网络请求拦截器只对非网页请求生效
            interceptors.addAll(client.networkInterceptors());
          }
          // 真正访问服务器的拦截器
          interceptors.add(new CallServerInterceptor(forWebSocket));
          // 创建RealInterceptorChain对象, 注意此时的index为0
          Interceptor.Chain chain = new RealInterceptorChain(interceptors, transmitter, null, 0,
              originalRequest, this, client.connectTimeoutMillis(),
              client.readTimeoutMillis(), client.writeTimeoutMillis());
          boolean calledNoMoreExchanges = false;
          try {
            // 调用RealInterceptorChain.proceed() 接收参数是Request
            Response response = chain.proceed(originalRequest);
            ...
            return response;
          } 
          ...
        }
    }
}

RealInterceptorChain.proceed(originalRequest)

public final class RealInterceptorChain implements Interceptor.Chain {
    public Response proceed(Request request, Transmitter transmitter, @Nullable Exchange exchange)
        throws IOException {
      ...
      // 注意此时的index为index+1,回想之前的一步,创建RealInterceptorChain时候, index是为0.
      // 可以看出来这里用的是责任链设计模式.  
      // 拦截器链最后就是一个递归调用, 最后调用到 CallServerInterceptor才开始真正的请求网络,然后再一步步将请求到的数据从拦截器返回来. 
      RealInterceptorChain next = new RealInterceptorChain(interceptors, transmitter, exchange,
          index + 1, request, call, connectTimeout, readTimeout, writeTimeout);
      // 上一步中index为0,那么这个 Interceptor 类型就是错误重定向拦截器
      Interceptor interceptor = interceptors.get(index);
      // 这里的next还是RealInterceptorChain对象. 下面看下错误重定向请求拦截器
      Response response = interceptor.intercept(next);
      ...
      return response;
    }
}

RetryAndFollowUpInterceptor.intercept(next)

public final class RetryAndFollowUpInterceptor implements Interceptor {
    @Override public Response intercept(Chain chain) throws IOException {
      Request request = chain.request();
      RealInterceptorChain realChain = (RealInterceptorChain) chain;
        ...
        try {
          // 这样一个循环最后又回到了RealInterceptorChain中的proceed()方法中了,此时的RealInterceptorChain中属性index为1.
          // 这样一个循环就会将所有的 Interceptor都调用到. 
          response = realChain.proceed(request, transmitter, null);
          success = true;
        } 
        ...
    }
}

总结

OkHttp的底层是通过Java的Socket发送HTTP请求与接受响应的,OkHttp实现了连接池的概念,即对于同一主机的多个请求,其实可以共用一个Socket连接,而不是每次发送完 HTTP请求就关闭底层的Socket,这样就实现了连接池的概念。而OkHttp对Socket的读写操作使用的OkIo库进行了一 层封装。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章