OKHttp3使用原理和源码解析

简介

OKHttp3是支持http1和http2网络协议的java和Android网络SDK,OKHttp依赖OKIO。

组成部分

1、OKHttpClient
OKHttpClient类组合了多个对象,实现Call.Factory接口,提供一个newCall方法,返回realcall(call的具体实现类),使用OKHttpClient最好创建一个单例,因为每一个client都有自己的一个连接池connection pool和一个线程池thread pool,重用这些连接池和线程池,可以减少延迟和节省内存。

/**
   * 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 */);
  }

2、Dispatcher
可以理解为一个策略,调用newcall的时候,不断的从RequestQueue中取出请求;
调用同步方法,直接返回Response,代码如下:

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

调用异步方法,把当前请求添加到请求队列,并通过回调的方式返回结果,代码如下:

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

当call.enqueue时候,也就是调用dispatcher.enqueue,值得注意的是,dispatcher.enqueue方法中,当前异步请求队列数量小于最大数量64,且同一host请求数量小于5,则把请求加入运行队列,交由线程池来解决,否在放入等待队列,代码如下:

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

3、interceptor
是OKHttp核心类,把网络请求、缓存、压缩等功能统一起来,每一个功能都是一个interceptor,再连成一个interceptor.chain,完成一个网络请求,代码如下:

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

流程图

在这里插入图片描述

总结

1、通过OKHttpClient创建一个call,发送同步或者异步请求;
2、OKHttp通过dispatcher对所有的realcall(call的具体实现类)进行统一管理并请求进行处理;
3、execute()和enqueue()最终都会调用到realcall的getResponseWithInterceptorChain(),从拦截器中获取结果;
4、拦截器中,依次通过责任链模式调用RetryAndFollowUpInterceptor(重定向拦截器)、BridgeInterceptor(桥拦截器)、cacheInterceptor(缓存拦截器)、ConnectInterceptor(连接拦截器)、CallServerInterceptor(网络拦截器),对请求依次处理,取得返回结果。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值