Okhttp3源码分析

okhttp3源码分析之AsyncTimeout 继承自Timeout, 使后台线程在发生超时时准确执行操作。用来实现本机不支持的超时。 公开方法: final void enter() 调用了private static synchronized void scheduleTimeout,确定链表关系(当前node上个的next和this的header前后关系)。 private static synchronized void s... 阅读详情

okhttp3源码分析基于okhttp3.10.0。

关于okhttp的特点及相关功能的介绍可以查看官网的介绍:

  1. http://square.github.io/okhttp/
  2. https://github.com/square/okhttp/wiki

基本使用

使用okhttp发起一次网络请求,只需要以下流程即可:

  1. 创建OkHttpClient
  2. 创建Request对象
  3. 创建一个Call对象,用于发起请求
  4. 发起网络请求(同步请求execute; 异步请求enqueue)

代码演示:

public void request()  {

    // 1、创建OkHttpClient
    OkHttpClient okHttpClient = new OkHttpClient();

    // 2、创建Request请求
    Request request = new Request.Builder()
            .url("https://blog.youkuaiyun.com/kaifa1321")
            .build();

    // 3、创建一个Call对象,用于发起请求
    Call call = okHttpClient.newCall(request);

    // 4、发起网络请求

    // 4.1、执行一个同步请求,获取Response
    Response response = call.execute();

    // 4.2、执行一个异步请求,通过Callback获取Response
    call.enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {}

        @Override
        public void onResponse(Call call, Response response) throws IOException {
            // 处理响应
            String string = response.body().string();
        }
    });
}

源码分析

针对上文中提到的okhttp的使用流程,这里将对这些流程的源码逐一分析。

创建OkHttpClient实例

OkHttpClient对象的创建,okhttp中提供了两种方式:

  • 通过无参数构造方法创建OkHttpClient
  • 通过OkHttpClient内部类Builder,使用建造者模式创建OkHttpClient实例
// 1、构造方法创建OkHttpClient
OkHttpClient okHttpClient = new OkHttpClient();

// 2、通过Builder创建OkHttpClient
OkHttpClient okHttpClient = new OkHttpClient.Builder()
        .addInterceptor(null)
        .cache(null)
        .build();

OkHttpClient实例化过程

这里看下OkHttpClient的构造方法:

public OkHttpClient() {
    this(new OkHttpClient());
}

OkHttpClient(Builder builder) {
    // 这不是该方法的完成代码,具体请看源码
    this.dispatcher = builder.dispatcher;
    this.interceptors = Util.immutableList(builder.interceptors);
    this.cache = builder.cache;
    this.internalCache = builder.internalCache;

    this.connectTimeout = builder.connectTimeout;
    this.readTimeout = builder.readTimeout;
    this.writeTimeout = builder.writeTimeout;

}

通过上面源码可以得知,OkHttpClient的无参构造方法最后也是通过创建一个Builder对象,完成OkHttpClient的实例化。其实无参参构造方法实例化OkHttpClient和通过Builder.build()方法实例化原理上完全一样,都是通过创建一个Builder对象初始化OkHttpClient,唯一不同的是Builder对象参数(系统默认和开发者自己设置)

这里看下Builder.build()方法

public OkHttpClient build() {
   // 这个this就是Builder对象本身
  return new OkHttpClient(this);
}

OkHttpClient通过建造者模式完成实例化,这种创建模式在okhttp中有使用非常多,例如Request、Response的创建都使用了该模式。

定制化OkHttpClient实例

在okhttp的官网中建议开发者在使用okhttp时,OkHttpClient的实例最好是通过单一实例,这样可以更好的管理okhttp的连接池和线程池。
但是,一般在应用开发中,会遇到一些特殊的请求,比如添加一个拦截器、添加缓存等的操作。如果我们直接修改单一实例的OkHttpClient,这样势必会影响其他的请求,okhttp也考虑到了这种情况,也给我们提供给了定制化OkHttpClient实例的方法newBuidler。

  OkHttpClient client = new OkHttpClient();
  client.newBuilder()
          .readTimeout(10, TimeUnit.SECONDS)
          .writeTimeout(10, TimeUnit.SECONDS)
          .build();

这里看下newBuilder方法

  public Builder newBuilder() {
    // this就是OkHttpClient单一实例
    return new Builder(this);
  }

通过已有的OkHttpClient实例创建一个新的Builder对象,这个Builder对象默认持有原来OkHttpClient实例的属性,这样就可以完全复用存在的OkHttpClient的相关设置,只需要对一些特定的属性做出修改即可。例如readTimeout,writeTimeout等。

创建Request对象

Request对象的主要作用就是封装Http请求的主要参数,这些参数包括:

  • url
  • http请求方式:GET、POST等
  • 请求体RequestBody,POST等请求方式时需要
  • http请求头

Request对象和OkHttpClient一样,也是通过建造者模式创建的.

创建Request对象:

    Request request = new Request.Builder()
        .url("https://api.github.com/repos/square/okhttp/issues")
        .header("User-Agent", "OkHttp Headers.java")
        .addHeader("Accept", "application/json; q=0.5")
        .addHeader("Accept", "application/vnd.github.v3+json")
        .post(RequestBody.create(MediaType, File))
        .build();

Request的创建流程相对简单,在上面中基本能够一目了然,这里就不做过多的介绍了。

在上面的代码示例中,需要注意的就是在Request中添加Header请求头的方法header()和addHeader()

在Request的源码中也对两个方法做了具体说明:

  • header():设置唯一的请求头键值对,如果存在相同name的请求头,value将会被覆盖。
  • addHeader():对相同name的请求头可以设置多个Value

RequestBody

在Request的创建过程中,如果该Request是一个POST请求,那么需要为该Request创建一个请求体RequestBody,RequestBody的创建需要调用静态方法create(),RequestBody中有几个重载的create()方法,主要针对不同的请求体类型创建请求体实例。

这里看下RequestBody类的具体内容。

    public abstract class RequestBody {
        // 请求体类型
        public abstract @Nullable MediaType contentType();

        // 请求体长度
        public long contentLength() throws IOException {
            return -1;
        }


        // 将请求体内容写到sink,sink是okio中的类,可以理解成输出流
        public abstract void writeTo(BufferedSink sink) throws IOException;

        /**
         * 创建一个请求体,
         */
        public static RequestBody create(@Nullable MediaType contentType, String content) {
            // 使用UTF-8编码
            Charset charset = Util.UTF_8;
            if (contentType != null) {
                charset = contentType.charset();
                if (charset == null) {
                    charset = Util.UTF_8;
                    contentType = MediaType.parse(contentType + "; charset=utf-8");
                }
            }
            byte[] bytes = content.getBytes(charset);
            return create(contentType, bytes);
        }

        /**
         * 创建请求体
         */
        public static RequestBody create(
                final @Nullable MediaType contentType, final ByteString content) {
            return new RequestBody() {
                @Override public @Nullable MediaType contentType() {
                    return contentType;
                }

                @Override public long contentLength() throws IOException {
                    return content.size();
                }

                @Override public void writeTo(BufferedSink sink) throws IOException {
                    sink.write(content);
                }
            };
        }

        /**
         * 创建请求体
         */
        public static RequestBody create(final @Nullable MediaType contentType, final byte[] content) {
            return create(contentType, content, 0, content.length);
        }


        /**
         * 创建请求体
         */
        public static RequestBody create(final @Nullable MediaType contentType, final byte[] content,
                                         final int offset, final int byteCount) {
            if (content == null) throw new NullPointerException("content == null");
            Util.checkOffsetAndCount(content.length, offset, byteCount);
            return new RequestBody() {
                @Override public @Nullable MediaType contentType() {
                    return contentType;
                }

                @Override public long contentLength() {
                    return byteCount;
                }

                @Override public void writeTo(BufferedSink sink) throws IOException {
                    // 将请求体内容写出到sink
                    sink.write(content, offset, byteCount);
                }
            };
        }

        /**
         * 创建一个请求体,请求体类型为file,一般文件上传时使用
         */
        public static RequestBody create(final @Nullable MediaType contentType, final File file) {
            if (file == null) throw new NullPointerException("content == null");

            return new RequestBody() {
                @Override public @Nullable MediaType contentType() {
                    return contentType;
                }

                @Override public long contentLength() {
                    return file.length();
                }

                @Override public void writeTo(BufferedSink sink) throws IOException {
                    Source source = null;
                    try {
                        source = Okio.source(file);
                        sink.writeAll(source);
                    } finally {
                        Util.closeQuietly(source);
                    }
                }
            };
        }
    }

这里给出核心代码


public static class Builder {

    Headers.Builder headers;

    public Builder header(String name, String value) {
      headers.set(name, value);
      return this;
    }

    public Builder addHeader(String name, String value) {
      headers.add(name, value);
      return this;
    }
}


public final class Headers {

    final List<String> namesAndValues = new ArrayList<>(20);

    // 添加一组键值对
    public Builder add(String name, String value) {
      checkNameAndValue(name, value);
      return addLenient(name, value);
    }


    // 添加唯一键值对
    public Builder set(String name, String value) {
      checkNameAndValue(name, value);
      // 如果存在,移除
      removeAll(name);
      addLenient(name, value);
      return this;
    }

    // 添加到list集合中
    Builder addLenient(String name, String value) {
      namesAndValues.add(name);
      namesAndValues.add(value.trim());
      return this;
    }
}

创建Call对象

// 3、创建一个Call启动请求
Call call = okHttpClient.newCall(request);

在okHttpClient.newCall()方法方法中通过调用RealCall.newRealCall()方法获取一个Call(RealCall)实例。

@Override 
public Call newCall(Request request) {
    // 获取一个Call(RealCall)对象
    return RealCall.newRealCall(this, request, false /* for web socket */);
}

发起网络请求

详见下节:Call接口及实现类RealCall

Call接口及实现类RealCall

Call

Call接口,主要实现网络请求调用。

  • 通过execute方法实现同步请求获取请求响应。
  • 通过enqueue方法实现异步请求通过CallBack回调获取请求响应。


Call接口源码

public interface Call extends Cloneable {

  // 返回原始请求对象
  Request request();

  // 同步请求
  Response execute() throws IOException;

  // 异步请求
  void enqueue(Callback responseCallback);

  // 取消请求
  void cancel();

  // 是否正在执行
  boolean isExecuted();

  // 是否取消
  boolean isCanceled();

  Call clone();

  interface Factory {
    Call newCall(Request request);
  }
}

RealCall

RealCall是Call接口的唯一实现类,因此okhttp的网络请求都是在RealCall类里面实现的。
所以这里将会对RealCall做详细的分析。

创建RealCall实例

在上文中说到,RealCall对象是在okHttpClient.newCall()方法中通过调用RealCall.newRealCall方法完成创建的。

这里看下RealCall.newRealCall()方法:

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.eventListener = client.eventListenerFactory().create(call);
    return call;
}

在该方法中,主要就是通过构造方法完成RealCall对象的创建,并且该RealCall对象持有了OkHttpClient和Requst实例。

RealCall对象创建以后,就可以开始正式的网络请求了,这里主要分为同步请求和异步请求。


// 执行一个同步请求,获取Response
try {
    Response response = call.execute();
} catch (IOException e) {
    e.printStackTrace();
}


// 执行一个异步请求,通过Callback获取Response
call.enqueue(new Callback() {
    @Override
    public void onFailure(Call call, IOException e) {}

    @Override
    public void onResponse(Call call, Response response) throws IOException {
        // 处理响应
        String string = response.body().string();
    }
});

这里对这两个请求方式一一分析。

execute同步请求

RealCall.execute()

  public Response execute() throws IOException {

    // 1、首先判断该Call是否执行
    synchronized (this) {
      if (executed) throw new IllegalStateException("Already Executed");
      executed = true;
    }
    captureCallStackTrace();
    eventListener.callStart(this);


    try {

      // 2、调用OkHttpClient中的dispatcher的executed方法
      client.dispatcher().executed(this);

      // 3、通过拦截器链获取http响应Response
      Response result = getResponseWithInterceptorChain();
      if (result == null) throw new IOException("Canceled");
      return result;
    } catch (IOException e) {
      eventListener.callFailed(this, e);
      throw e;
    } finally {

      // 4、结束请求,从同步请求队列中移除该Call
      client.dispatcher().finished(this);
    }
  }

在execute()方法中主要完成了以下功能:

  1. 首先,判断该请求是否被执行,一个Call智能执行一次
  2. 其次,调用OkHttpClient.dispatcher对象的executed方法将请求放入到同步请求队列中。
  3. 然后,通过okhttp中的拦截器链获取http响应
  4. 最后,通过调用OkHttpClient.dispatcher对象的finished()方法结束请求(这个将在下文中Dispatcher分发器中具体分析)

在同步请求中,最终通过RealCall.getResponseWithInterceptorChain()方法获取响应,通过这个方法的名字也能知道该方法的作用:通过拦截器链获取响应。

核心功能:Dispatcher分发器。
这个将在后续的章节中做具体的分析,这里只需要知道同步异步请求最终都是在Dispatcher请求分发器中完成的即可


核心功能:Interceptor拦截器。
这个将在后续的章节中做具体的分析,这里只需要知道获取Http响应是通过Intercepter拦截器中完成的即可。

enqueue异步请求

RealCall.enqueue(Callback)

  @Override 
  public void enqueue(Callback responseCallback) {

        // 1、首先判断该Call是否执行
        synchronized (this) {
          if (executed) throw new IllegalStateException("Already Executed");
          executed = true;
        }
        captureCallStackTrace();
        eventListener.callStart(this);

        // 创建一个AsyncCall对象,将对象放入到异步队列中
        client.dispatcher().enqueue(new AsyncCall(responseCallback));
  }

在enqueue()方法中主要完成了以下功能:

  1. 首先,判断该请求是否被执行,一个Call只能执行一次
  2. 然后,调用OkHttpClient.dispatcher对象的enqueue()方法将请求添加到异步请求队列中被执行。

在上面enqueue方法中,最后执行client.dispatcher().enqueue(new AsyncCall(responseCallback))时,创建了一个AsyncCall对象。

这里需要对这个AsyncCall做进一步分析。

AsyncCall

AsyncCall是RealCall的一个内部类,AsyncCall继承自NamedRunnable,而NamedRunnable实现了Runnable接口,所以AsyncCall主要作用就是实现Runnable接口。

NamedRunnable

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

NamedRunnable是一个抽象类,实现了Runnable接口,在该类中定义了一个抽象方法execute(),主要就是实现具体的异步操作,这里对该类就不做过多解释了。

接下来主要看下NamedRunnable的子类AsyncCall

AsyncCall

  final class AsyncCall extends NamedRunnable {
    private final Callback responseCallback;

    AsyncCall(Callback responseCallback) {
      super("OkHttp %s", redactedUrl());
      this.responseCallback = responseCallback;
    }

    String host() {
      return originalRequest.url().host();
    }

    Request request() {
      return originalRequest;
    }

    RealCall get() {
      return RealCall.this;
    }

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

在AsyncCall的execute方法中主要作用就两个:

  • 通过RealCall.getResponseWithInterceptorChain()方法获取请求响应,这个和同步请求方法中调用的是同一个方法。

  • 在获取网络响应后,通过调动 client.dispatcher().finished(this)将该请求从异步请求队列中移除,表示该请求已经处理完,并让线程池执行其他异步等待队列中的请求。

看到这里想必你就清楚了,异步处理流程和上文中RealCall.execute()同步请求是完全一样的,唯一不同的就是一个是在主线程中完成的,一个是在子线程(AsyncCall)中完成的。

关于Dispatcher分发器和Interceptor拦截器将在下面章节中具体介绍。

OkHttp3源码分析-BridgeInterceptor BridgeInterceptor BridgeInterceptor主要用于网络请求的构建,和响应的解析。 public final class BridgeInterceptor implements Interceptor { @Override public Response intercept(Chain chain) throws IOException { ... 阅读详情

相关推荐

OKHttp3源码分析——学习笔记

文章目录1. HttpClient与HttpUrlConnection的区别2. OKHttp源码分析使用步骤:dispatcher任务调度器,Request请求RealCallAsyncCall3. OKHttp架构分析1. 异步请求线程池, Dispather2. 连接池清理线程池- ConnectionPool3. 缓存整理线程池 DisLruCache4. Http2异步事务线程池, ht...

Sincerity_的博客 1380

OkHttp3源码详解

OkHttp3源码详解

QG 1915

PostgreSQL数据库全攻略:从入门到精通

本文是一份PostgreSQL数据库综合指南,涵盖安装配置、基础操作和高级管理。主要内容包括:1) PostgreSQL简介与各平台安装方法;2) 数据库基本操作,如创建数据库/表、CRUD操作、用户权限管理;3) 高级功能包括索引优化、事务控制、视图、存储过程、触发器和扩展模块;4) 数据库管理维护,涉及配置调优、备份恢复、性能监控和日常维护;5) 安全设置与高可用方案。指南提供了从入门到进阶的实用知识,强调结合官方文档进行深入学习,帮助用户高效使用这一功能强大的开源关系型数据库系统。

索大神的博客 1970

OkHttp3源码解析 - 请求流程

在Android蛮荒年代,我们做网络请求通常会选用HttpURLConnection或者Apache HTTP Client,这两者均支持HTTPS、流的上传和下载、配置超时和连接池等特性,但随着业务场景的复杂化以及对流量消耗的优化需求,OkHttp应运而生。现在谈起网络请求,大家肯定下意识想到的就是 okHttp 或者 retrofit 这样的三方请求库。

Android百晓生的博客 1072

告别误唤醒!S32K3xx低功耗设计避坑指南:Fast Standby模式与WISR寄存器操作详解

本文深入解析了NXP S32K3xx系列MCU在低功耗设计中常见的误唤醒问题,并提供了基于Fast Standby模式的解决方案。文章重点剖析了DCMRWF5寄存器的配置方法、WISR/WISR_64唤醒中断状态寄存器的标志位处理策略,以及如何利用32KB Standby SRAM保存唤醒状态,从而帮助开发者构建稳定可靠的汽车电子低功耗系统。

weixin_29163857的博客 362

可调电源的电路设计

可调电源在电路调试中经常用到,可调电源分为两种2-5v(非0点可调)和0-5v(低至0点可调)可调两种。 对于第一种非0点电压的可调范围,其主要是由于开关电源或LDO芯片输出的最小电压为一个固定电压值,非0范围。因此通过调节开关电源或LDO端的反馈电阻的设计模型,其电压可调范围都与芯片的参考电压有关。 基于开关电源的可调电压设计电路 因芯片U2的输出参考电压VSENSE管脚为1.22v。因此,通过调节可调电阻R8的数值,其芯片输出的最低电压一定不小于1.22v。当然此种方案是手动可调输出电压的设计,如

weixin_42257266的博客 9731

OkHttp3源码解析(高工视角)

本文解读的OkHttp版本是3.14.9,拉取自master分支的parent-3.14.9(tag);这是OkHttp团队将okhttp项目migrate to Kotlin前的最后一个版本。java是最...算了不拉仇恨了^_^。 1.http/1.1 2.http/2.0

m0_37840695的博客 843

华为AC外置Portal认证方案配置步骤指南

华为AC外置Portal认证方案配置步骤指南

m0_46129105的博客 7675

OkHttp3源码解析--设计模式

看到这篇文章的人不知道有多少是和我一样的Android程序员。35岁,这是我们这个行业普遍的失业高发阶段,这种情况下如果还不提升自己的技能,进阶发展,我想,很可能就是本行业的职业生涯的终点了。我们要有危机意识,切莫等到一切都成定局时才开始追悔莫及。只要有规划的,有系统地学习,进阶提升自己并不难,给自己多充一点电,你才能走的更远。千里之行始于足下。这是上小学时,那种一元钱一个的日记本上每一页下面都印刷有的一句话,当时只觉得这句话很短,后来渐渐长大才慢慢明白这句话的真正的含义。

2301_79985012的博客 891

告别混乱接线!用EPLAN 3D布局图,手把手教你搞定电气柜的3D建模与自动布线

本文详细介绍了如何使用EPLAN 3D布局图进行电气柜的3D建模与自动布线,帮助工程师告别混乱接线。从项目准备、基础结构建模到智能设备布局与逻辑定义,再到高级布线技术与问题排查,提供了一套完整的实战指南。通过EPLAN的3D功能,显著提升设计效率与系统可靠性。

weixin_30680385的博客 340

SAP MTO实战:从销售订单到生产订单的精准触发与配置详解

本文深入解析SAP系统中按订单生产(MTO)模式的核心流程与配置。详细阐述了如何通过精准配置物料主数据策略组、需求类型及计划策略(如策略50),实现从销售订单自动触发生产订单的完整链路。文章结合实战案例,指导用户打通销售与生产环节,并提供了关键事务代码与常见问题排查指南,助力企业实现以销定产,优化库存与成本控制。

weixin_29300931的博客 215

OKHttp3 源码阅读 - Kotlin版本

OKHttp 是由 Square 公司开源的,广泛应用于 Android 开发中,并且是 Retrofit 的底层实现。它是一个高效的 HTTP 客户端,适用于 Android 和 Java 应用程序。它支持 HTTP/2、连接池、GZIP 压缩、缓存等功能,能够帮助开发者更高效地处理网络请求。从 Android 4.4 开始 HttpURLConnection 的底层实现采用的是OKHttp。OkHttp是一个功能强大且灵活的HTTP客户端库,适用于各种网络请求场景。

Bonnie_cat的博客 1158

【2026-Spark实验一-Windows中安装Spark环境】

本文详细介绍了在Windows系统中配置Spark 3.5.8开发环境的完整流程。主要内容包括:安装JDK 8并配置环境变量,下载并解压Spark 3.5.8预编译版,设置SPARK_HOME系统变量,配置Hadoop的winutils工具解决Windows兼容性问题。通过spark-shell和SparkPi示例程序验证环境配置成功,确保Spark能够正常运行分布式计算任务。文中特别强调了路径命名规范、环境变量设置顺序等关键细节,提供了完整的配置截图和验证方法,帮助开发者快速搭建稳定的Spark学习环境。

pblh123的专栏 1587

okhttp3 底层源码分析

okhttp3源码分析之请求流程:链接地址 okhttp3源码分析之拦截器:链接地址

悟-静的博客 553

深信服全产品线新版图标库 Visio版+PPT版【2023年最新整理】

深信服全产品线新版图标库Visio版(含网络位置符号以及其他网络设备和外设图标)有朋友想要我整理一下深信服的相关图标,那么今天,瑞哥给老铁们整理了。运维漫谈是瑞哥针对运维领域的一个公众号,欢迎大家的关注哦!篇幅原因,就只展示那么多,有需要的朋友自行下载。SANGFOR 各产品图标-Visio版。你好,这里是网络技术联盟站。SANGFOR全产品线图标。深信服设备前置面板-AC。

网络技术联盟站 3694

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

【OkHttp3源码分析】

OkHttp3源码分析

u012632105的博客 121

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

OkHttp3源码分析-缓存与CacheInterceptor

基本结构 CacheInterceptor依赖两个关键类,一个是CacheStrategy,一个是InternalCache。 CacheStrategy采用的是简单工厂模式(其实只是抽象工厂的特例),此类用于判定使用缓存,网络还是二者都使用。 InternalCache基本不会自己去设置,会使用Cache中的InternalCache的结构,而Cache实际上是通过DiskLruCache实现...

wfeii的博客 600

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

Android OkHttp3源码分析

title: Android OkHttp3源码分析 date: 2019-06-03 21:16:50 tags: Android第三方框架 文章目录title: Android OkHttp3源码分析 date: 2019-06-03 21:16:50 tags: Android第三方框架Android OkHttp3源码分析介绍源码分析简单使用OkHttpClient的创建Request的...

hesheng1024的博客 2663

OKHttp3.14源码分析记录

OkHttp是一个处理网络请求的开源项目,是Android端最火热的轻量级框架,由移动支付Square公司贡献用于替代HttpUrlConnection和Apache HttpClient。随着OkHttp的不断成熟,越来越多的Android开发者使用OkHttp作为网络框架。 1、首先推荐看以下几篇文章《OkHttp 3.7源码分析》,了解OKHttp的整体框架以及重要的拦截器模块。 OkHttp源码分析——整体架构 OkHttp源码分析——拦截器 OkHttp源码分析...

天空24的专栏 388

OkHttp3源码分析

基本用法 平常开发Android App的时候,经常用到OkHttp,不能只停留在会用的阶段,还要知道其原理。今天就来分析一下OkHttp3的源码。 POST请求的基本用法如下: OkHttpClient client = new OkHttpClient.Builder().build(); FormBody body = new FormBody.Builder() ...

acaixuediannao的专栏 1023

Okhttp3源码分析之三

从Okhttp3源码分析之一可知,调用Call的enqueue执行最终的请求 //1.创建OkHttpClient对象 OkHttpClient okHttpClient = new OkHttpClient(); //2.创建Request对象,设置一个url地址(百度地址),设置请求方式。 Request request = ...

jy专栏 233

Okhttp3源码分析之一

一、OKHTTP简介 OKHttp是一个处理网络请求的开源项目OKHttp GitHub地址 OKHttp优点 支持HTTP2/SPDY(SPDY是Google开发的基于TCP的传输层协议,用以最小化网络延迟,提升网络速度,优化用户的网络使用体验。) socket自动选择最好路线,并支持自动重连,拥有自动维护的socket连接池,减少握手次数,减少了请求延迟,共享Socket,减少对服务器...

jy专栏 334

okhttp3源码分析之请求流程

okhttp3源码分析之请求流程 前言 在Android开发中,当下最火的网络请求框架莫过于okhttp和retrofit,它们都是square公司的产品,两个都是非常优秀开源库,值得我们去阅读它们的源码,学习它们的设计理念,但其实retrofit底层还是用okhttp来发起网络请求的,所以深入理解了okhttp也就深入理解了retrofit,它们的源码阅读顺序应该是先看okhttp,我在retr...

Kelvin的专栏 366

Okhttp3源码分析之二

从Okhttp3源码解析之一了解到,使用OKHTTP执行一个http请求需要四步 一、接下来分析一下Request: public final class Request { final HttpUrl url;//请求地址 final String method;//请求模式post、get……等 final Headers headers;//请求头 final @Nul...

jy专栏 275
上一篇: UML 类图和时序图
下一篇: Okhttp3源码分析(2) Dispatcher分发器
Kerwin zhang
博客等级 码龄12年 21粉丝 28原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值