OkHttp源码--整体架构

OkHttp的整体架构大致可以分为以下几层:

  • Interface(接口层):接受网络访问请求
  • Protocol(协议层):处理协议逻辑
  • Connection(连接层):管理网络连接,发送新的请求,接收服务器访问
  • Cache(缓存层):管理本地缓存
  • I/O(I/O层):实际数据读写实现
  • Inteceptor(拦截器层):拦截网络访问,插入拦截逻辑

image

Interface(接口层)

接收用户的网络访问请求(同步/异步),发起实际的网络访问。
OkHttpClient是okhttp框架的客户端,用户使用okhttp进行各种设置,发起各种网络请求都是通过OkHttpClient完成的。每个OkHttpClient内部都维护了属于自己的任务队列,连接池,Cache,拦截器等,所以应该全局共享一个OkHttpClient实例。
Call描述一个实际的访问请求,用户的每一个网络请求都是一个Call实例。Call本身是一个接口,实际执行过程中,okhttp会为每一个请求创建一个RealCall,每个RealCall里面有一个AsyncCall

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;
    }

    /**
     * Attempt to enqueue this async call on {@code executorService}. This will attempt to clean up
     * if the executor has been shut down by reporting the call as failed.
     */
    void executeOn(ExecutorService executorService) {
     ...
    }

    @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接口。

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();
}

由此看出每一个Call都是一个线程,执行Call的过程就是执行其execute方法的过程。
Dispatcher是okhttp的任务队列,其内部维护了一个线程池,当接收到一个Call时,Dispatcherf负责在线程池中找到空闲的线程并执行其execute方法。

Protocol(协议层)

OkHttp支持http1/http2/WebSocket协议,在3.7版本放弃了Spdy协议。鼓励开发者使用http2。

Connection(连接层)

连接层中有一个连接池,统一管理所有的Socket连接,当用户新发起一个网络请求时,OkHttp会首先从连接池中查找是否有符合要求的连接,如果有则直接通过该连接发送网络请求,否则新创建一个网络连接。

RealConnection描述一个物理Socket连接,连接池中维护多个RealConnection实例。由于HTTP2支持多路复用,一个RealConnection可以支持多个网络访问请求。

StreamAllocation来描述一个实际的网络请求开销(从逻辑上一个Stream对应一个Call,但在实际网络请求过程中一个Call常常涉及到多次请求。如重定向,Authenticate等场景。所以准确地说,一个Stream对应一次请求,而一个Call对应一组有逻辑关联的Stream),一个RealConnection对应一个或多个StreamAllocation,所以StreamAllocation可以看做是RealConenction的计数器,当RealConnection的引用计数变为0,且长时间没有被其他请求重新占用就将被释放。

Cache(缓存层)

当用户的网络请求在本地已有符合要求的缓存时,okhttp会直接从缓存中返回结果,节省网络开销。

I/O(I/O层)

实际的数据读写,有高效的I/O库okio

Inteceptor(拦截器层)

提供了一个AOP(面向切向编程:涉及到众多模块的某一类问题进行统一管理)接口,方便用户可以切入到各个层面对网络访问进行拦截并执行相关逻辑。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值