Okhttp源码分析--基本使用流程分析

本文详细分析了Okhttp的基本使用流程,包括同步和异步请求的创建步骤。同步请求通过execute发送,异步请求通过enqueue执行。Okhttp采用构造者模式简化设置,使用拦截器链处理请求,Dispatcher管理并发请求。同步请求在主线程执行,异步请求在工作线程执行,两者最后都会移除Call。
摘要由CSDN通过智能技术生成

Okhttp源码分析--基本使用流程分析

一、 使用

同步请求
    OkHttpClient okHttpClient=new OkHttpClient();
    Request request=new Request.Builder()
        .get()
        .url("www.baidu.com")
        .build();
    Call call =okHttpClient.newCall(request).execute();
异步请求
  OkHttpClient okHttpClient=new OkHttpClient();
    Request request=new Request.Builder()
        .get()
        .url("www.baidu.com")
        .build();
    Call call=okHttpClient.newCall(request).enqueue(new Callback() {
      @Override public void onFailure(Call call, IOException e) {
        Log.i(TAG, "onFailure: ");
      }

      @Override public void onResponse(Call call, Response response) throws IOException {
        Log.i(TAG, "onResponse: ");
      }
    });

可以看出不管是同步还是异步请求,使用okhttp大致分为3个步骤:
1. 创建okhttpclient
2. 创建请求的request
3. 通过client拿到call、发送请求

注:okhttpclient和request的创建均可采用构造者模式,在构造过程中可根据自己的实际需求设置相应的参数,如可在okhttpclient构造时添加自定义拦截器,在request构造过程中设置连接超时时间等。

二、 源码分析

首先看下OkhttpClient这个类,使用步骤的第一步就是构造OkhttpClient对象。

先贴下官方对OkhttpClient的定义

 *Factory for {@linkplain Call calls}, which can be used to send HTTP requests and read their
 * responses.
 * OkHttpClients should be shared
 
 * OkHttp performs best when you create a single {@code OkHttpClient} instance and reuse it for
 * all of your HTTP calls. This is because each client holds its own connection pool and thread
 * pools. Reusing connections and threads reduces latency and saves memory. Conversely, creating a
 * client for each request wastes resources on idle pools.

OkhttpClient是用于发送请求和读取响应的,官方建议创建一个单例的OkHttpClient,并且所有的http请求都复用它。因为每个OkHttpClient都有自己的connection pool and thread pool。复用connection pool and thread pool可以节约内存,相反如果为每个请求都创建一个OkHttpClient那么会浪费idle pools中的资源。

创建OkHttpClient有两种方式:
1、通过构造函数
2、通过Builder()创建一个client并自定义设置

同时还提供了一个newBuilder()来自定义client,它跟共享的client拥有相同的connection pool, thread pools, and configuration。我们可以用该方法来获取特定设置的client。

OkHttpClient提供无参构造函数,由代码可知它在内部调用OkHttpClient的有参构造函数
,在有参构造函数里对OkHttpClient主要属性做了初始化赋值。

  public OkHttpClient() {
    this(new Builder());
  }
  
  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;
    ...//省略N行
  }

下面贴下OkHttpClient主要的属性

public class OkHttpClient{
    final Dispatcher dispatcher;//分发器
    final @Nullable Proxy proxy;//代理
    final List<Protocol> protocols;//协议
    final List<ConnectionSpec> connectionSpecs;//传输层版本和连接协议
    final List<Interceptor> interceptors;//拦截器 (okhttp核心机制)
    final List<Interceptor> networkInterceptors;//网络拦截器
    final EventListener.Factory eventListenerFactory;
    final ProxySelector proxySelector;//代理选择器
    final CookieJar cookieJar;//cookie
    final @Nullable
    Cache cache;//cache 缓存
    final @Nullable
    InternalCache internalCache;//内部缓存
    final SocketFactory socketFactory;//socket 工厂
    final @Nullable
    SSLSocketFactory sslSocketFactory;//安全套层socket工厂 用于https
    final @Nullable
    CertificateChainCleaner certificateChainCleaner;//验证确认响应书,适用HTTPS 请求连接的主机名
    final HostnameVerifier hostnameVerifier;//主机名字确认
    final CertificatePinner certificatePinner;//证书链
    final Authenticator proxyAuthenticator;//代理身份验证
    final Authenticator authenticator;//本地省份验证
    final ConnectionPool connectionPool;//链接池 复用连接
    final Dns dns; //域名
    final boolean followSslRedirects;//安全套接层重定向
    final boolean followRedirects;//本地重定向
    final boolean retryOnConnectionFailure;//连接失败是否重试
    final int connectTimeout;//连接超时时间
    final int readTimeout;//读取超时时间
    final int writeTimeout;//写入超时时间
}

通过浏览源码我们可以发现OkHttpClient采用了构造者设计模式,这样简化参数设置,降低使用成本。比如我们前面简单使用的例子

OkHttpClient类还有一个需要了解的函数就是newCall,因为OkHttpClient实现Call.Factory接口所以覆写了newCall方法,在方法内部返回的是一个RealCall实例。

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

OkHttpClient构造好了之后接下来就是创建request,request就是我们要发送的请求。它也是通过builder模式构造的。下面贴下Request的主要属性以及其构造函数。

public final class Request {
  final HttpUrl url;//请求url地址
  final String method;//请求方式
  final Headers headers;//请求头
  final @Nullable RequestBody body;//请求body
  final Map<Class<?>, Object> tags;//请求ta
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值