TencentはOkhttp3に謙虚になり、一連の学習経験をまとめました

最近、OKhttp3は比較的主流のネットワーク要求フレームワークです。インタビューの中で、okhttp3をよく理解しているかどうかをよく尋ねます。この記事では、okhttp3の原則(非使用、自分でBaiduを使用)、およびソースコードに基づいてOKhttp3を分析する偉大な神々による優れた記事をまとめました。

1.まず、偉大な神々によるOKhttp3のソースコード分析:(再現)

Android OkHttp(3)ソースコード分析:https ://blog.csdn.net/zxw136511485/article/details/52872724(これはokhttpのソースコード分析です。この記事に従って最初の記事を読み、okhtttpソースコードを自分で確認しました。参照okhttpの内部では、おそらくこの記事でokhttpの内部構造について説明しています。いくつかの言語エラーがありますが、この記事はokhttpについても説明しています。一般的な状況を理解するには、まずこの記事を読むことをお勧めします)

okhttpソースコード分析:https ://blog.csdn.net/json_it/article/details/78404010 (これは2番目の記事で、私が最近読んでいる記事です。偉大な神の分析は比較的完全で正確です。okhttp3の詳細分析)

OkHttp3ソースコード分析[レビュー]:https ://blog.csdn.net/json_it/article/details/78404010 (これは5つの部分に分かれたソースコード分析です。分析も非常に優れており、表示に適しています)

Android okhttp3は、ソケットの基礎となる実装追跡を作成します。https://blog.csdn.net/hello2mao/article/details/53159151 (この記事では、OKhttp3ソケットの基礎となる実装について説明します)

OkHttp3のソースコードとデザインパターン:
https : //www.imooc.com/article/24025?block_id=tuijian_wz(この記事では、デザインパターンの観点からOKhttp3を分析しています)

RealCallに関するOkHttp3のコメント。最初のコメントはDispatcherです。

https://blog.csdn.net/dingding_android/article/details/51942000

2.あなたが読んだ記事とソースコードに基づいて、私は簡単な要約を作りました

OKhttp3:次の側面から要約する

okHttp3が使いやすいのはなぜですか?

OkHttpは、以下の機能を備えた洗練されたネットワークリクエストライブラリです。

1)http2をサポートし、マシンへのすべてのリクエストが同じソケットを共有します

2)組み込みの接続プール、接続の再利用のサポート、遅延の削減

3)透明なgzip圧縮応答ボディをサポート

4)キャッシングによるリクエストの繰り返しを避ける

5)リクエストが失敗すると、ホストの他のIPが自動的に再試行され、自動的にリダイレクトされます

6)使いやすいAPI

ネットワーク要求の実装方法:

OkHttp3の最下層はSocketであり、URLConnectionではありません。プラットフォームのClass.forName()を反映して、現在のランタイムで使用されているソケットライブラリを取得します。

ソケットがネットワーク要求を開始するプロセスは、一般的に次のとおりです:
(1)。ソケットオブジェクトを作成する;
(2)。ターゲットネットワークに接続する;

(3)。入力および出力ストリーム操作を実行します。

(1)(2)の実現は接続インターフェースにカプセル化され、特定の実装クラスはRealConnectionです。
(3)ストリームインターフェースを介して実装されます。異なるネットワークプロトコルに応じて、Http1xStreamとHttp2xStreamの2つの実装クラスがあります。
ネットワーク接続を作成する時間は比較的長いため(HTTPの場合、3ウェイハンドシェイクが必要)、リクエストは頻繁に断片化、したがってネットワーク接続の効率を向上させるために、OKHttp3はネットワーク接続の再利用を実現します

使用したデザインパターン:

单例模式:(建议用单例模式创建okHttpClient)OkHttpClient, 可以通过 new OkHttpClient() 或 new OkHttpClient.Builder() 来创建对象, 但是---特别注意, OkHttpClient() 对象最好是共享的, 建议使用单例模式创建。 因为每个 OkHttpClient 对象都管理自己独有的线程池和连接池。 这一点很多同学,甚至在我经历的团队中就有人踩过坑, 每一个请求都创建一个 OkHttpClient 导致内存爆掉

外观模式 : OKHttpClient 里面组合了很多的类对象。其实是将OKHttp的很多功能模块,全部包装进这个类中,让这个类单独提供对外的API,这种设计叫做外观模式(外观模式:隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口)

Builder模式 : OkHttpClient 比较复杂, 太多属性, 而且客户的组合需求多样化, 所以OKhttp使用建造者模式(Build模式:使用多个简单的对象一步一步构建成一个复杂的对象,一个 Builder 类会一步一步构造最终的对象)

工厂方法模式:Call接口提供了内部接口Factory(用于将对象的创建延迟到该工厂类的子类中进行,从而实现动态的
配置,工厂方法模式。(工厂方法模式:这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。)

享元模式:在Dispatcher的线程池中,所用到了享元模式,一个不限容量的线程池 , 线程空闲时存活时间为 60 秒。线程池实现了对象复用,降低线程创建开销,从设计模式上来讲,使用了享元模式。(享元模式:尝试重用现有的同类对象,如果未找到匹配的对象,则创建新对象,主要用于减少创建对象的数量,以减少内存占用和提高性能)

责任链模式:很明显,在okhttp中的拦截器模块,执行过程用到。OkHttp3 的拦截器链中, 内置了5个默认的拦截器,分别用于重试、请求对象转换、缓存、链接、网络读写(责任链模式:为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为型模式。在这种模式中,通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。)

策略模式 :CacheInterceptor 实现了数据的选择策略, 来自网络还是来自本地? 这个场景也是比较契合策略模式场景, CacheInterceptor 需要一个策略提供者提供它一个策略(锦囊), CacheInterceptor 根据这个策略去选择走网络数据还是本地缓存。
缓存的策略过程:
1、 请求头包含 "If-Modified-Since" 或 "If-None-Match" 暂时不走缓存
2、 客户端通过 cacheControl 指定了无缓存,不走缓存
3、客户端通过 cacheControl 指定了缓存,则看缓存过期时间,符合要求走缓存。

4、 如果走了网络请求,响应状态码为 304(只有客户端请求头包含 "If-Modified-Since" 或 "If-None-Match" ,服务器数据没变化的话会返回304状态码,不会返回响应内容), 表示客户端继续用缓存。

(策略模式:一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。策略对象改变 context 对象的执行算法。)

源码中用到的几个重要的类及作用解释:

1.OkhttpClient :对外的API,OKHttp的很多功能模块,全部包装进这个类;创建分为两种:一种是new OkHttpClient()的方式,另一种是使用建造者(Builder)模式 -- new OkHttpClient.Builder()....Build()。那么这两种方式有什么区别呢?

第一种:new OkHttpClient(),OkHttp做了很多工作,很多我们需要的参数在这里都获得默认值,也就是默认值设定。

第二种:默认的设置和第一种方式相同,但是我们可以利用建造者模式单独的设置每一个属性;
注意事项:OkHttpClient强烈建议全局单例使用,因为每一个OkHttpClient都有自己单独的连接池和线程池,复用连接池和线程池能够减少延迟、节省内存。

2.RealCall类:集成Call类,从源代码中,可看到使用Call类,发送出(同步/异步)请求.RealCall的主要作用:发送请求,当中还有拦截器的建立过程,异步回调。

3.Dispatcher类(调度器,多线程):保存同步和异步Call的地方,并负责执行异步AsyncCall

4.拦截器链:有用户自定义的interceptor、retryAndFollowUpInterceptor、BridgeInterceptor、CacheInterceptor、ConnectInterceptor、 networkInterceptors、CallServerInterceptor。依次通过以上拦截器,传递给RealCall中的ApplicationInterceptorChain。拦截器之所以可以依次调用,并最终再从后先前返回Response,都依赖于ApplicatiionInterceptorChain的proceed方法.

5.HttpEngine类:OKhttp底层的实现,(还在看)

缓存策略:提到缓存策略,就要提到CacheInterceptor拦截器,如下图

CacheStrategy实现缓存策略,CacheStrategy使用Factory模式进行构造,该类决定是使用缓存还是使用网络请求

Cache是封装了实际的缓存操作;
DiskLruCache:Cache基于DiskLruCache;

线程池(同步,异步):

针对异步请求,Dispatcher使用了两个Deque,一个保存准备执行的请求,一个保存正在执行的请求,为什么要用两个呢?因为Dispatcher默认支持最大的并发请求是64个,单个Host最多执行5个并发请求,如果超过,则Call会先被放入到readyAsyncCall中,当出现空闲的线程时,再将readyAsyncCall中的线程移入到runningAsynCalls中,执行请求。

如果正在执行的请求总数<=64 && 单个Host正在执行的请求<=5,则将请求加入到runningAsyncCalls集合中,紧接着就是利用线程池执行该请求,否则就将该请求放入readyAsyncCalls集合中。

总结

【Android 详细知识点思维脑图(技能树)】

其实Android开发的知识点就那么多,面试问来问去还是那么点东西。所以面试没有其他的诀窍,只看你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。

虽然 Android 没有前几年火热了,已经过去了会四大组件就能找到高薪职位的时代了。这只能说明 Android 中级以下的岗位饱和了,现在高级工程师还是比较缺少的,很多高级职位给的薪资真的特别高(钱多也不一定能找到合适的),所以努力让自己成为高级工程师才是最重要的。

这里附上上述的面试题相关的几十套字节跳动,京东,小米,腾讯、头条、阿里、美团等公司19年的面试题。把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节。

由于篇幅有限,这里以图片的形式给大家展示一小部分。

详细整理在石墨文档可以见;

Android架构视频+BAT面试专题PDF+学习笔记​

网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。

原文作者:茶卡y
原文链接:https://blog.csdn.net/u012881042/article/details/79759203

おすすめ

転載: blog.csdn.net/AndroidAlvin/article/details/107379139