OkHttp源码解析

OkHttp源码解析

基本使用

val okhttp = OkHttpClient.Builder()
      .build()
val request = Request.Builder()
      .url("https://www.baidu.com")
      .get()
      .build()
val call = okhttp.newCall(request)
call.enqueue(object : Callback{
    override fun onFailure(call: Call, e: IOException) {
    }

    override fun onResponse(call: Call, response: Response) {
    }
})
  • 通过构造者模式创建OkHttpClient对象,其中可以设置拦截器等参数,在build()方法后正式确认赋值
  • 通过构造这模式创建Request对象,其中可以设置url等参数,同样通过build()方法后正式确认赋值
  • 通过newCall得到Call对象
  • 通过enqueue进行异步网络请求

Call对象的获取

/**
   * Prepares the {@code request} to be executed at some point in the future.
   */
  @Override public Call newCall(Request request) {
    return RealCall.newRealCall(this, request, false /* for web socket */);
  }

Call为接口类,RealCall.newRealCall方法中RealCallCall的实现类,调用RealCallnewRealCall方法得到Call对象的实例。

call.enqueue方法

调用RealCallenqueue方法,

@Override public void enqueue(Callback responseCallback) {
    synchronized (this) {
      if (executed) throw new IllegalStateException("Already Executed");
      executed = true;
    }
    captureCallStackTrace();
    eventListener.callStart(this);
    client.dispatcher().enqueue(new AsyncCall(responseCallback));
  }

通过同步锁操作,禁止enqueue方法调用2次,否则会抛出异常IllegalStateException
client.dispatcher()Dispatcher类对象的实例。

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

Dispatcher类中,定义了maxRequests最大请求并发数,maxRequestsPerHost每台主机的同时最大请求数和3个队列。分别为缓存队列,异步请求队列和同步请求队列。

在调用Dispatcherenqueue()方法时

synchronized void enqueue(AsyncCall call) {
    if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {
      runningAsyncCalls.add(call);
      executorService().execute(call);
    } else {
      readyAsyncCalls.add(call);
    }
  }

会对队列的长度和最大请求数等进行判断,小于即添加到异步请求队列中,通过线程池executorService().execute(call)进行执行。

ExecutorService线程池

public synchronized ExecutorService executorService() {
    if (executorService == null) {
      executorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS,
          new SynchronousQueue<Runnable>(), Util.threadFactory("OkHttp Dispatcher", false));
    }
    return executorService;
  }

其中线程池设定了核心线程数为0,最大线程数为Integer.MAX_VALUE,当前线程结束后复用时间为60s,若60s之前则复用,否则有新的请求后要重新创建。参数五为队列,存放当前同时进行的所有请求。参数六为线程工厂为了设定线程名和是否是守护线程。

executorService().execute(call)方法

此方法执行参数的为Runnable。其中AsyncCall继承Runnable,所以执行了AsyncCallexecute方法。

@Override protected void execute() {
      boolean signalledCallback = false;
      try {
        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) {
        if (signalledCallback) {
          // Do not signal the callback twice!
          Platform.get().log(INFO, "Callback failure for " + toLoggableString(), e);
        } else {
          eventListener.callFailed(RealCall.this, e);
          responseCallback.onFailure(RealCall.this, e);
        }
      } finally {
        client.dispatcher().finished(this);
      }
    }
  • signalledCallback参数用于区分错误是OkHttp还是我们自己代码的错误。若通过responseCallback的回调,则为truecatch异常捕获后则为用户自己的错误。否则未调用回调,则为OkHttp自己的错误。
  • client.dispatcher().finished(this)无论结果如何,都会走finally代码块的finished方法将其关闭。

getResponseWithInterceptorChain()

Response response = getResponseWithInterceptorChain()

通过getResponseWithInterceptorChain()获得返回的Response结果。

Response getResponseWithInterceptorChain() throws IOException {
    // Build a full stack of interceptors.
    List<Interceptor> interceptors = new ArrayList<>();
    interceptors.addAll(client.interceptors());
    interceptors.add(retryAndFollowUpInterceptor);
    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, null, null, null, 0,
        originalRequest, this, eventListener, client.connectTimeoutMillis(),
        client.readTimeoutMillis(), client.writeTimeoutMillis());

    return chain.proceed(originalRequest);
  }

通过责任链的模式对拦截器的添加。
首先添加自己设定的interceptor应用拦截器,然后依次执行retryAndFollowUpInterceptor重定向拦截器、BridgeInterceptor含有请求头信息的桥接拦截器、CacheInterceptor缓存拦截器(其中会对数据没有变化的值直接返回)、ConnectInterceptor、自己设定的networkInterceptors()网络拦截器,最后为和服务器真正交互的CallServerInterceptor拦截器。获取服务器数据后同样依次返回Response

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值