分享好友 最新动态首页 最新动态分类 切换频道
最全OkHttp源码解析(小白必看,建议收藏),聪明人已经收藏了
2024-12-27 11:27

最后

由于篇幅原因,就不多做展示了

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

4、响应码


  • 1** 信息,服务器收到请求,需要请求者继续执行操作

  • 2** 成功,操作被成功接收并处理

  • 3** 重定向,需要进一步的操作以完成请求

  • 4** 客户端错误,请求包含语法错误或无法完成请求

  • 5** 服务器错误,服务器在处理请求的过程中发生了错误

5、socket 概念


套接字(socket)是通信的基石,是支持 TCP/IP 协议的网络通信的基本操作单元。它是网络通信过程中端点的抽象表示,包含进行网络通信必须的五种信息:连接使用的协议,本地主机的 IP 地址,本地进程的协议端口,远地主机的 IP 地址,远地进程的协议端口。

6.责任链模式(设计模式


意图:避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。

主要解决:职责链上的处理者负责处理请求,客户只需要将请求发送到职责链上即可,无须关心请求的处理细节和请求的传递,所以职责链将请求的发送者和请求的处理者解耦了。

优点: 1、降低耦合度。它将请求的发送者和接收者解耦。 2、简化了对象。使得对象不需要知道链的结构。 3、增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任。 4、增加新的请求处理类很方便。

使用场景: 1、有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定。 2、在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。 3、可动态指定一组对象处理请求。

在Android开发中,学过自定义view的应该也知道:ViewGroup 事件传递的递归调用就类似一条责任链,一旦其寻找到责任者,那么将由责任者持有并消费掉该次事件,具体体现在 View 的 onTouchEvent 方法中返回值的设置,如果 onTouchEvent 返回 false,那么意味着当前 View 不会是该次事件的责任人,将不会对其持有;如果为 true 则相反,此时 View 会持有该事件并不再向下传递。

下面开始为正文内容


一、OkHttp介绍

=========================================================================

1.这个库的作用


网络底层库,它是基于 http 协议封装的一套请求客户端,虽然它也可以开线程,但根本上它更偏向真正的请求,跟 HttpClient, HttpUrlConnection 的职责是一样的。其中封装了网络请求 get、post 等底层操作的实现。

2.项目中使用这个库的原因(优点


  • OkHttp 提供了对最新的 HTTP 协议版本 HTTP/2 和 SPDY的支持,这使得对同一个主机发出的所有请求都可以共享相同的套接字连接。

  • 如果 HTTP/2 和 SPDY 不可用,OkHttp 会使用连接池来复用连接以提高效率。

  • OkHttp 提供了对 GZIP 的默认支持来降低传输内容的大小。

  • OkHttp 也提供了对 HTTP 响应的缓存机制,可以避免不必要的网络请求

  • 当网络出现问题时,OkHttp 会自动重试一个主机的多个 IP 地址。

二、简单使用步骤

=======================================================================

1.导入库


implementation(“com.squareup.okhttp3:okhttp:3.10.0”)

2.步骤


  • 1.先创建 OkHttpClient 实例;

  • 2.构造 Request 实例,传入 url 等相关参数

  • 3.通过前两步中的实例对象构建 Call 对象

  • 4.异步请求通过 Call#enqueue(Callback) 方法来提交异步请求,同步请求通过 Call#execute() 直接 获取Reponse

相应代码如下

//1.创建⼀个 OkHttp 的实例

OkHttpClient client = new OkHttpClient.Builder().build();

//2.创建 Request

Request request = new Request.Builder().url(“http://www.jimengjia.com”).build();

//3.构建 Call 对象

Call call=okHttpClient.newCall(request);

//4.通过 Call#enqueue(Callback) 方法来提交异步请求

call.enqueue(new Callback() {

@Override

public void onFailure( Call call, IOException e) {

}

@Override

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

}

});

3.源码解析


看源码的流程(思想

1.从使用步骤中第四步可以看出起关键作用的是enqueue,所以从源码中找到此方法开始分析。

代码如下

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

}

2.从上述代码可以看到,创建了一个 AsyncCall 并将Callback传入后,最后交给了任务分发器 Dispatcher 来进一步处理。

client.dispatcher().enqueue(new AsyncCall(responseCallback));

进入下一个调用dispatcher().enqueue()

synchronized void enqueue(AsyncCall call) {

if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {

//运行中的队列

runningAsyncCalls.add(call);

executorService().execute(call);

} else {

//等待中的队列,可看成支线

readyAsyncCalls.add(call);

}

}

相应的对象如下

private int maxRequests = 64;

private int maxRequestsPerHost = 5;

//可以很明显看出是添加到了runningAsyncCalls,readyAsyncCalls中

private final Deque readyAsyncCalls = new ArrayDeque<>();

private final Deque runningAsyncCalls = new ArrayDeque<>();

此方法的大致内容:对请求的入队做了一些限制,若正在执行的请求数量小于最大值(默认64,并且此请求所属主机的正在执行任务小于最大值(默认5,就加入正在运行的队列并通过线程池来执行该任务,否则加入准备执行队列中。

3.从上述代码可以看到,当满足条件后将进入executorService()

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;

}

这里的具体就是放到线程池里的运行了。(以下内容为拓展

ExecutorService的创建方式如下:所有线程池最终都是通过这个方法来创建的。

public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,

BlockingQueue workQueue,ThreadFactory threadFactory,

RejectedExecutionHandler handler)

  • corePoolSize :核心线程数,一旦创建将不会再释放。如果创建的线程数还没有达到指定的核心线程数量,将会继续创建新的核心线程,直到达到最大核心线程数后,核心线程数将不在增加;如果没有空闲的核心线程,同时又未达到最大线程数,则将继续创建非核心线程;如果核心线程数等于最大线程数,则当核心线程都处于激活状态时,任务将被挂起,等待空闲线程来执行。

  • maximumPoolSize :最大线程数,允许创建的最大线程数量。如果最大线程数等于核心线程数,则无法创建非核心线程;如果非核心线程处于空闲时,超过设置的空闲时间,则将被回收,释放占用的资源。

  • keepAliveTime : 也就是当线程空闲时,所允许保存的最大时间,超过这个时间,线程将被释放销毁,但只针对于非核心线程。

  • unit : 时间单位,TimeUnit.SECONDS等。

  • workQueue : 任务队列,存储暂时无法执行的任务,等待空闲线程来执行任务。

  • threadFactory : 线程工程,用于创建线程。

  • handler : 当线程边界和队列容量已经达到最大时,用于处理阻塞时的程序

可以明显的看到创建时使用的队列为SynchronousQueue:它内部没有容器(可以去拓展一下,本文就不写了

4.进入到下一个代码区execute()

@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 {

//维护,执行完之后,调用dispatcher中的finish函数

client.dispatcher().finished(this);

}

}

5.可以明显的看到处理请求的为getResponseWithInterceptorChain()方法

//责任链模式的设计

//(从一些维度来优化,如用户流量,响应速度,减少服务器承受的压力)

Response getResponseWithInterceptorChain() throws IOException {

// Build a full stack of interceptors.

List interceptors = new ArrayList<>();

//这一个是用来加自己的拦截器

interceptors.addAll(client.interceptors());

//下面是通用的

interceptors.add(retryAndFollowUpInterceptor);

interceptors.add(new BridgeInterceptor(client.cookieJar()));

最后

由于文案过于长,在此就不一一介绍了这份Java后端架构进阶笔记内容包括:Java集合,JVM、Java并发、微服务、SpringNetty与 RPC 、网络、日志 、Zookeeper 、Kafka 、RabbitMQ 、Hbase 、MongoDB、Cassandra 、Java基础、负载均衡、数据库、一致性算法、Java算法、数据结构、分布式缓存等等知识详解。

本知识体系适合于所有Java程序员学习,关于以上目录中的知识点都有详细的讲解及介绍,掌握该知识点的所有内容对你会有一个质的提升其中也总结了很多面试过程中遇到的题目以及有对应的视频解析总结。

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

数据结构、分布式缓存**等等知识详解。

[外链图片转存中…(img-w5G6Ugah-1715578863588)]

本知识体系适合于所有Java程序员学习,关于以上目录中的知识点都有详细的讲解及介绍,掌握该知识点的所有内容对你会有一个质的提升其中也总结了很多面试过程中遇到的题目以及有对应的视频解析总结。

[外链图片转存中…(img-olIalVJm-1715578863589)]

[外链图片转存中…(img-FskkZlp5-1715578863589)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

最新文章
行业视角 | 哈尔滨骏展雷克萨斯总经理董占全:探秘黑龙江最大雷克萨斯店,人效与服务的博弈!
我们集团在整个黑龙江省有9家店,其中有7家是在哈尔滨,有两家是在整个黑龙江省外的,整个集团一共是9家店。那我们骏展雷克萨斯可以这么讲,是整个黑龙江省建筑面积是最大的一个雷克萨斯的经销商店。那整个建地面积是15,000平,建筑面积的
抖音开通膳食营养类目准备什么资料?开通具体步骤分享 今年快速渠道
在数字经济飞速发展的今天,短视频平台已经成为了各类品牌宣传、产品推广的重要渠道。抖音作为国内Zui受欢迎的短视频平台之一,凭借其强大的用户基数和丰富的内容生态,吸引了无数企业和个人入驻。如果你打算在抖音上开通膳食营养类目账号
用尖端科技赋能低空城市起降场数智运行
转自:天津日报  “忽如一夜春风来,千树万树梨花开”。低空经济作为战略性新兴产业融合发展的新赛道,已成为推动社会经济创新发展的新引擎。城市起降场作为低空经济的主要基础设施之一,其数智运行程度直接影响了低空经济的整体运行水平
详解人工智能领域重大突破:GPT-3
英语原文:Exploring GPT-3: A New Breakthrough in Language Generation翻译:雷锋字幕组GPT-3是什么?我们讨论15亿参数的 Generative Pretrained Transformer-2(GPT-2)的延迟发布是否合理,似乎还是去年的事情。如果你觉得其实没过多久
,掌握这些技巧,让百度轻松收录你的网站内容
在当今数字化时代,拥有一个网站对于个人和企业来说至关重要,仅仅拥有一个网站是不够的,更重要的是让百度等搜索引擎收录你的网站内容,以便更多的人能够找到你的网站,怎样才能让百度收录网站内容显示呢?下面将为大家介绍一些实用的技巧
谷歌chrome浏览器2023安卓最新
谷歌chrome浏览器是一款快速、安全且功能丰富的网络浏览器,干净整洁的界面以及快速地浏览速度带给用户舒适的使用体验,多功能的特点使用户可以畅快的浏览互联网、享受便捷的上网体验。网页翻译 - 您可以轻松浏览任何语言的网页节省数据流
这些A股光存储概念股名单,你需要知道!(12月12日)
  据南方财富网概念查询工具数据显示,相关光存储概念股:  1、中电兴发002298:12月12日消息,中电兴发5日内股价上涨13.23%,该股最新报6.880元涨3.28%,成交7.58亿元,换手率16.78%。  公司于2020年2月19日晚间披露2019年度非公开
都江堰seo优化价格【百度都江堰】
文章都江堰seo优化价格【百度都江堰】由网友旧时月色投稿,希望给你工作学习带来帮助。在当今数字化时代,搜索引擎优化(SEO)对于企业和个人的在线存在至关重要,都江堰作为一个充满活力和发展潜力的城市,也有许多企业和个人希望通过 SEO
构建个人投资组合网站:从基础到进阶
在数字时代,个人投资组合网站成为展示工作成果、技能和专业身份的不可或缺的平台。构建这样的网站不仅可以增强职业形象,还能在求职和客户互动中发挥关键作用。本章将引导你从零开始,详细探讨构建个人投资组合网站的整
谷歌浏览器ipad版
谷歌浏览器ipad版是专门针对苹果ipad设备而开发的一款平板电脑浏览器,全新的外观融入了Material Design设计元素,图形更醒目、操作更流畅、触感更灵敏,能够带给用户流畅的上网体验。另外本款google chrome浏览器ipad版同时还具备网页翻译
相关文章
推荐文章
发表评论
0评