OkHttp源码--发送请求

OkHttpClient

一般可以通过以下两种方式创建OkhttpClient

OkHttpClient client = new OkHttpClient();
OkHttpClient client = new OkHttpClient.Builder().build();

看一下OkHttpClient构造方法的源码

  public OkHttpClient() {
    // new Builder()也是做了一些初始化配置
    this(new Builder());
  }
  // 主要利用传入的Builder对象初始了OkHttpClient的成员,还有一些初始化工作
  OkHttpClient(Builder builder) {
    this.dispatcher = builder.dispatcher;
    this.proxy = builder.proxy;
    this.protocols = builder.protocols;
    this.connectionSpecs = builder.connectionSpecs;// OkHttp连接配置
    this.interceptors = Util.immutableList(builder.interceptors);
    this.networkInterceptors = Util.immutableList(builder.networkInterceptors);
    this.eventListenerFactory = builder.eventListenerFactory;// 一个Call的状态监听器
    this.proxySelector = builder.proxySelector;
    this.cookieJar = builder.cookieJar;// 默认是没有Cookie的
    this.cache = builder.cache;
    this.internalCache = builder.internalCache;
    this.socketFactory = builder.socketFactory;

    boolean isTLS = false;
    for (ConnectionSpec spec : connectionSpecs) {
      isTLS = isTLS || spec.isTls();
    }

    if (builder.sslSocketFactory != null || !isTLS) {
      this.sslSocketFactory = builder.sslSocketFactory;
      this.certificateChainCleaner = builder.certificateChainCleaner;
    } else {
      X509TrustManager trustManager = Util.platformTrustManager();
      this.sslSocketFactory = newSslSocketFactory(trustManager);
      this.certificateChainCleaner = CertificateChainCleaner.get(trustManager);
    }

    if (sslSocketFactory != null) {
      Platform.get().configureSslSocketFactory(sslSocketFactory);
    }

    this.hostnameVerifier = builder.hostnameVerifier; // 安全相关的设置
    this.certificatePinner = builder.certificatePinner.withCertificateChainCleaner(
        certificateChainCleaner);
    this.proxyAuthenticator = builder.proxyAuthenticator;
    this.authenticator = builder.authenticator;
    this.connectionPool = builder.connectionPool;
    this.dns = builder.dns; // 域名解析系统
    this.followSslRedirects = builder.followSslRedirects;
    this.followRedirects = builder.followRedirects;
    this.retryOnConnectionFailure = builder.retryOnConnectionFailure;
    this.callTimeout = builder.callTimeout;
    this.connectTimeout = builder.connectTimeout;
    this.readTimeout = builder.readTimeout;
    this.writeTimeout = builder.writeTimeout;
    this.pingInterval = builder.pingInterval; // 这个就和WebSocket有关了。为了保持长连接,我们必须间隔一段时间发送一个ping指令进行保活

    if (interceptors.contains(null)) {
      throw new IllegalStateException("Null interceptor: " + interceptors);
    }
    if (networkInterceptors.contains(null)) {
      throw new IllegalStateException("Null network interceptor: " + networkInterceptors);
    }
  }

OkHttpClient的静态内部类Builder

主要工作就是封装了外部类需要的参数,并提供了一种比较方便的链式调用方法初始化一个类的成员变量,最后传给外部类完成初始化得到外部对象。

public static final class Builder {
    Dispatcher dispatcher;
    @Nullable Proxy proxy;
    List<Protocol> protocols;
    List<ConnectionSpec> connectionSpecs;
    final List<Interceptor> interceptors = new ArrayList<>();
    final List<Interceptor> networkInterceptors = new ArrayList<>();
    EventListener.Factory eventListenerFactory;
    ProxySelector proxySelector;
    CookieJar cookieJar;
    ...

    // 对成员变量赋初值
    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();
      ...
    }

    // 使用OkHttpClient对成员变量赋值
    Builder(OkHttpClient okHttpClient) {
      this.dispatcher = okHttpClient.dispatcher;
      this.proxy = okHttpClient.proxy;
      this.protocols = okHttpClient.protocols;
      this.connectionSpecs = okHttpClient.connectionSpecs;
      this.interceptors.addAll(okHttpClient.interceptors);
      this.networkInterceptors.addAll(okHttpClient.networkInterceptors);
      this.eventListenerFactory = okHttpClient.eventListenerFactory;
      this.proxySelector = okHttpClient.proxySelector;
      this.cookieJar = okHttpClient.cookieJar;
      ...
    }
    
    // 方法返回本身使其可以链式调用
    public Builder callTimeout(long timeout, TimeUnit unit) {
      callTimeout = checkDuration("timeout", timeout, unit);
      return this;
    }
    ...
    // 将此Builder对象传入OkHttpClient构造器
    public OkHttpClient build() {
      return new OkHttpClient(this);
    }
}

Request

创建方式:

Request request = new Request.Builder()
                .url("http://www.baidu.com")
                .get()
                .build();

可以看出用的也是Builder模式

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

    Builder(Request request) {
      this.url = request.url;
      this.method = request.method;
      this.body = request.body;
      this.tags = request.tags.isEmpty()
          ? Collections.emptyMap()
          : new LinkedHashMap<>(request.tags);
      this.headers = request.headers.newBuilder();
    }

Call

该对象代表一个准备被执行的请求,Call是可以被取消的,Call对象代表了一个request/response 对(Stream)一个call对象一定只能执行一次

创建方式:

 Call call = client.newCall(request);

再来看下OkHttpClient的newCall方法:

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

OkHttpClient实现了Call接口内部的Factory接口,newCall()是Factory接口的抽象方法。
再来看newRealCall()方法,它是个静态方法:

  static RealCall newRealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {
    // Safely publish the Call instance to the EventListener.
    // 构造方法是私有的   forWebSocket是否用在WebSocket
    RealCall call = new RealCall(client, originalRequest, forWebSocket);
    call.transmitter = new Transmitter(client, call);
    return call;
  }

RealCall的execute()

先来看下同步方法

  @Override public Response execute() throws IOException {
    synchronized (this) {
      // 首先判断该call是否被执行过,此处表明call对象一定只能执行一次
      if (executed) throw new IllegalStateException("Already Executed");
      executed = true;
    }
    // Transmitter类是OkHttp的应用层和网络层的一个桥梁类
    transmitter.timeoutEnter();
    transmitter.callStart();
    try {
      // client.dispatcher()返回的是client在Builder中初始的dispatcher成员变量
      client.dispatcher().executed(this);
      // 拿到响应,是拦截器链的开端
      return getResponseWithInterceptorChain();
    } finally {
      client.dispatcher().finished(this);
    }
  }

dispatcher的executed()

将call加入同步请求的执行队列中

  synchronized void executed(RealCall call) {
    runningSyncCalls.add(call);
  }

getResponseWithInterceptorChain()

将client中的拦截器和默认的拦截器都加入到集合中,将其传入创建了一个RealInterceptorChain拦截器链。最后返回chain的proceed()的返回值

Response getResponseWithInterceptorChain() throws IOException {
    // Build a full stack of interceptors.
    List<Interceptor> interceptors = new ArrayList<>();
    interceptors.addAll(client.interceptors());
    interceptors.add(new RetryAndFollowUpInterceptor(client));
    interceptors.add(new BridgeInterceptor(client.cookieJar()));
    interceptors.add(new CacheInterceptor(client.internalCache()));
    interceptors.add(new ConnectInterceptor(client));
    if (!forWebSocket) {
      interceptors.addAll(client.networkInterceptors());
    }
    interceptors.add(new CallServerInterceptor(forWebSocket));

    Interceptor.Chain chain = new RealInterceptorChain(interceptors, transmitter, null, 0,
        originalRequest, this, client.connectTimeoutMillis(),
        client.readTimeoutMillis(), client.writeTimeoutMillis());

    boolean calledNoMoreExchanges = false;
    try {
      Response response = chain.proceed(originalRequest);
      if (transmitter.isCanceled()) {
        closeQuietly(response);
        throw new IOException("Canceled");
      }
      return response;
    } catch (IOException e) {
      calledNoMoreExchanges = true;
      throw transmitter.noMoreExchanges(e);
    } finally {
      if (!calledNoMoreExchanges) {
        transmitter.noMoreExchanges(null);
      }
    }
}

dispatcher()的finished()

刚开始在dispatcher.executed()里把call加入到runningSyncCalls这个队列中,这里是将其删除。

void finished(RealCall call) {
    finished(runningSyncCalls, call);
}

private <T> void finished(Deque<T> calls, T call) {
    Runnable idleCallback;
    synchronized (this) {
      if (!calls.remove(call)) throw new AssertionError("Call wasn't in-flight!");
      idleCallback = this.idleCallback;
    }

    boolean isRunning = promoteAndExecute();

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

RealCall的equeue()

@Override public void enqueue(Callback responseCallback) {
    // 判断是否执行过
    synchronized (this) {
      if (executed) throw new IllegalStateException("Already Executed");
      executed = true;
    }
    transmitter.callStart();
    // 把这个回调接口封装成AsyncCall对象
    client.dispatcher().enqueue(new AsyncCall(responseCallback));
}

dispatcher.enqueue()

同步请求中只有一个队列,而这里有两个,一个为等待队列一个为执行队列

void enqueue(AsyncCall call) {
    synchronized (this) {
      // 异步请求的就绪队列
      readyAsyncCalls.add(call);

      // Mutate the AsyncCall so that it shares the AtomicInteger of an existing running call to
      // the same host.
      // 对异步调用进行变异,使其共享对同一主机的现有运行调用的atomicinteger(原子操作类)
      // atomicinteger能保证多个线程对同一个变量不会同时修改
      if (!call.get().forWebSocket) {
        // 在runningAsyncCalls队列或者readyAsyncCalls队列中找到和call同一主机的call对象
        AsyncCall existingCall = findExistingCallWithHost(call.host());
        if (existingCall != null) call.reuseCallsPerHostFrom(existingCall);
      }
    }
    promoteAndExecute();
}

dispatcher.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();
        // maxRequests最大并发请求数64
        if (runningAsyncCalls.size() >= maxRequests) break; // Max capacity.
        // maxRequestsPerHost 每个主机的最大请求数5  当前主机请求数大于等于主机最大请求数
        if (asyncCall.callsPerHost().get() >= maxRequestsPerHost) continue; // Host max capacity.

        i.remove();
        asyncCall.callsPerHost().incrementAndGet();
        executableCalls.add(asyncCall);
        runningAsyncCalls.add(asyncCall);
      }
      isRunning = runningCallsCount() > 0;
    }

    for (int i = 0, size = executableCalls.size(); i < size; i++) {
      AsyncCall asyncCall = executableCalls.get(i);
      // executorService()返回一个线程池对象
      // 真正的异步处理方法
      asyncCall.executeOn(executorService());
    }

    return isRunning;
}

AsyncCall

RealCall里面的内部类

final class AsyncCall extends NamedRunnable {
    private final Callback responseCallback;
    private volatile AtomicInteger callsPerHost = new AtomicInteger(0);

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

    AtomicInteger callsPerHost() {
      return callsPerHost;
    }

    void reuseCallsPerHostFrom(AsyncCall other) {
      this.callsPerHost = other.callsPerHost;
    }

    String host() {
      return originalRequest.url().host();
    }

    Request request() {
      return originalRequest;
    }

    RealCall get() {
      return RealCall.this;
    }

    // 尝试将此异步调用排队到{@code executorservice}。如果执行器已关闭,则此操作将尝试通过将调用报告为失败来进行清理。
    void executeOn(ExecutorService executorService) {
      assert (!Thread.holdsLock(client.dispatcher()));
      boolean success = false;
      try {
        // 让 ExecutorService 中的某個线程执行这個 Runnable 线程
        executorService.execute(this);
        success = true;
      } catch (RejectedExecutionException e) {
        InterruptedIOException ioException = new InterruptedIOException("executor rejected");
        ioException.initCause(e);
        transmitter.noMoreExchanges(ioException);
        responseCallback.onFailure(RealCall.this, ioException);
      } finally {
        if (!success) {
          client.dispatcher().finished(this); // This call is no longer running!
        }
      }
    }
    
    // 和RealCall的execute()方法很像
    @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);
        }
      } finally {
        client.dispatcher().finished(this);
      }
    }
 }

AsyncCall继承的NamedRunnable实现Runnable接口。run()里面调用了execute(),它是个抽象方法,具体实现在AsyncCall中。

public abstract class NamedRunnable implements Runnable {
  protected final String name;

  public NamedRunnable(String format, Object... args) {
    this.name = Util.format(format, args);
  }

  @Override public final void run() {
    String oldName = Thread.currentThread().getName();
    Thread.currentThread().setName(name);
    try {
      execute();
    } finally {
      Thread.currentThread().setName(oldName);
    }
  }

  protected abstract void execute();
}

流程图

在这里插入图片描述

Dispatcher

成员变量

  private int maxRequests = 64;
  private int maxRequestsPerHost = 5;
  private @Nullable Runnable idleCallback;

  /** Executes calls. Created lazily. */
  private @Nullable ExecutorService executorService;

  /** Ready async calls in the order they'll be run. */
  private final Deque<AsyncCall> readyAsyncCalls = new ArrayDeque<>();

  /** Running asynchronous calls. Includes canceled calls that haven't finished yet. */
  private final Deque<AsyncCall> runningAsyncCalls = new ArrayDeque<>();

  /** Running synchronous calls. Includes canceled calls that haven't finished yet. */
  private final Deque<RealCall> runningSyncCalls = new ArrayDeque<>();

executorService()

corePoolSize设置为0表示一旦有闲置的线程就可以回收

 public synchronized ExecutorService executorService() {
    if (executorService == null) {
      executorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS,
          new SynchronousQueue<>(), Util.threadFactory("OkHttp Dispatcher", false));
    }
    return executorService;
 }
 
 public ThreadPoolExecutor(
    int corePoolSize,   // 核心线程数,默认情况下核心线程会一直存活
    int maximumPoolSize,  // 线程池所能容纳的最大线程数
    long keepAliveTime,   // 非核心线程的闲置超时时间,超过这个时间就会被回收
    TimeUnit unit,      // keepAliveTime的单位
    BlockingQueue<Runnable> workQueue,  // 线程池中的任务队列
    ThreadFactory threadFactory // 线程工厂,提供创建新线程的功能
 )

Transmitter

OkHttp的应用程序和网络层之间的桥梁。 此类公开了高级应用程序层原语:连接,请求,响应和流。
RealCall负责的是请求发起和执行,Transmitter则负责请求任务的状态、超时时间、生命周期事件的更新以及请求任务背后的连接、连接池的维护管理等。

构造方法参数

  • OkHttpClient对象
  • RealConnectionPool连接池对象
  • RealCall
  • EventListener监听对象(则一个请求从发起到结束的所有步骤都会被EventListener“看”到)
  • AsyncTimeout超时控制

方法

public Timeout timeout()

返回AsyncTimeout对象

public void timeoutEnter()

创建超时控制

public void timeoutEarlyExit()

在呼叫完成之前停止超时控制

public void callStart()

调用eventListener的callStart方法(绑定call)

public void prepareToConnect(Request request)

准备创建一个流来承载{@code request}。 如果存在连接,则优先使用现有连接。

public boolean canRetry()

是否可以重试

public boolean hasExchange()

是否含有正在执行的交换

public void cancel()

中断请求

public boolean isCanceled()

是否可以中断请求
image

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值