首页 > 编程语言 >OKHttp的源码解读

OKHttp的源码解读

时间:2024-12-16 23:27:20浏览次数:9  
标签:请求 builder interceptors client 解读 源码 call OKHttp new

OKHttp的源码解读

使用实例

 OkHttpClient client = new OkHttpClient();
 Request request = new Request.Builder()
                .url("")
                .build();
 Response response;
 //同步请求
 response = client.newCall(request).execute();
 //异步请求
 client.newCall(request).enqueue(new Callback() {
     @Override
     public void onFailure(Call call, IOException e) {

     }

     @Override
     public void onResponse(Call call, Response response) throws IOException {

              }
          });
      } 

主要对象分析

在这里插入图片描述

1.OkHttpClient:使用构造器模式初始化了配置信息,包括分发器,超时时间、缓存、自定义拦截器,任务分发器。

 OkHttpClient(Builder builder) {
    this.dispatcher = builder.dispatcher;
    this.proxy = builder.proxy;
    this.protocols = builder.protocols;
    this.connectionSpecs = builder.connectionSpecs;
    this.interceptors = Util.immutableList(builder.interceptors);
    this.networkInterceptors = Util.immutableList(builder.networkInterceptors);
    this.eventListenerFactory = builder.eventListenerFactory;
    this.proxySelector = builder.proxySelector;
    this.cookieJar = builder.cookieJar;
    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;

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

2.Request:封装了请求所需要的请求方法(method),请求地址(url),请求头(header),请求体(body)

public final class Request {
  final HttpUrl url;
  final String method;
  final Headers headers;
  final @Nullable RequestBody body;
  final Map<Class<?>, Object> tags;
  ......
}

3.call:OkHttp中用于执行HTTP请求的主要接口。它提供了同步和异步两种执行请求的方式,并允许在请求完成后获取响应结果或处理异常。

public interface Call extends Cloneable {
  Request request();
  //同步请求
  Response execute() throws IOException;
  //异步请求
  void enqueue(Callback responseCallback);
  //取消
  void cancel();
  //是否被执行
  boolean isExecuted();
  //是否被取消
  boolean isCanceled();
  //超时设置
  Timeout timeout();
  //克隆call对象
  Call clone();
  //工厂模式创建call对象
  interface Factory {
    Call newCall(Request request);
  }
}

4.RealCall:RealCall是Call的实现类,连接了应用端与网络层的,负责请求的调度和内部逻辑的组织。

//通过newCall返回一个call对象
static RealCall newRealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {
    // Safely publish the Call instance to the EventListener.
    RealCall call = new RealCall(client, originalRequest, forWebSocket);
    call.transmitter = new Transmitter(client, call);
    return call;
  }

5.AsyncCall:是RealCall的一个内部类,也是一个Runnable。主要作用是封装异步请求的逻辑,并将其提交给OkHttp的调度器(Dispatcher)执行。它允许OkHttp在不阻塞当前线程的情况下,异步地处理网络请求,并在请求完成后通过回调接口通知调用者。

 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) {
      assert (!Thread.holdsLock(client.dispatcher()));
      boolean success = false;
      try {
        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!
        }
      }
    }

6.Dispatcher主要作用是维护请求的状态,管理请求队列,并确保在任何时间内并发请求数不超过设定的限制。它维护了一个线程池,用于执行请求,并实现了请求的排队、调度和执行逻辑。

public final class Dispatcher {
  /** 准备的异步请求队列 */
  private final Deque<AsyncCall> readyAsyncCalls = new ArrayDeque<>();

  /** 正在运行的异步队列,包括取消但还没有销毁的AsyncCall
  private final Deque<AsyncCall> runningAsyncCalls = new ArrayDeque<>();

  /** 正在运行的同步队列, 包含取消但是还没有销毁的RealCall*/
  private final Deque<RealCall> runningSyncCalls = new ArrayDeque<>();

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

}

拦截器

在RealCall文件里面,允许开发者在HTTP请求的生命周期中的不同阶段进行干预,以实现自定义的行为。例如,可以在请求被发送之前添加自定义的请求头,或者在响应被接收之后对响应体进行处理。

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

标签:请求,builder,interceptors,client,解读,源码,call,OKHttp,new
From: https://blog.csdn.net/weixin_39788742/article/details/144387294

相关文章