不懂网络组件?这一次爱奇艺大佬带你深度分析OkHttp源码与Retrofit封装,彻底了解!

2021-01-12 10:18:38 浏览数 (1)

我们项目当中的每个app都需要用到网络和服务器进行交互,在Android项目开发中使用HTTP协议完成通信的话,基本上都要用到OkHttp或者Retrofit。

主流网络组件主流网络组件

OkHttp和Retrofit是目前应用最为广泛的网络组件,面试几乎必问。

面试时问到比较开放性的问题,比如你觉得Retrofit有什么缺点?如何优化?

像这种问题其实没有标准答案,但是我们一定要对Retrofit的原理熟悉,并且结合自己的思想,说出自己的理解,能够解释清楚,逻辑是..顺畅的就没问题。

但是很多同学害怕这种类型的问题,因为大家应该都能够感受到自己更习惯按部就班的按照人家制定好的计划来学习,缺乏自己的思想。

面试之前也是疯狂去刷题,所以问到有标准答案的问题大家能去死记硬背,反而没那么害怕。

而如果在面试时,或者在开发中遇到没有“标准答案”的问题,那只能懵逼了。

OkHttp

OkHttp是一个高效的HTTP客户端,是目前Android使用最广泛的网络框架。它的横空出世,让其他的网络请求框架都变得黯然失色。

优点:

  • 支持Http1、Http2、Quic以及WebSocket;
  • 连接池复用底层TCP(Socket),减少请求延时;
  • 无缝的支持GZIP减少数据流量;
  • 缓存响应数据减少重复的网络请求;
  • 请求失败自动重试主机的其他ip,自动重定向;

Retrofit

准确来说,Retrofit 是一个 RESTful 的 HTTP 网络请求框架的封装。

原因:网络请求的工作本质上是 OkHttp 完成,而 Retrofit 仅负责网络请求接口的封装。

App应用程序通过Retrofit请求网络,实际上是使用Retrofit接口层封装请求参数、Header、Url 等信息,之后由 OkHttp 完成后续的请求操作。

在服务端返回数据之后,OkHttp 将原始的结果交给 Retrofit,Retrofit根据用户的需求对结果进行解析。

所以,网络请求的本质仍旧是OkHttp完成的,retrofit只是帮使用者来进行工作简化的,比如配置网络,处理数据等工作,提高这一系列操作的复用性。这也就是网上流行的一个不太准确的总结:OkHttp是瑞士军刀,retrofit则是将瑞士军刀包装成了一个非常好用的指甲钳。

Retrofit 对Okhttp做了什么

Retrofit并没有改变网络请求的本质,也无需改变,因为OkHttp已经足够强大,Retrofit的封装可以说是很强大,里面涉及到一堆的设计模式,可以通过注解直接配置请求,可以使用不同的http客户端,虽然默认是用http,可以使用不同Json Converter 来序列化数据,同时提供对RxJava的支持,使用Retrofit OkHttp RxJava可以说是目前比较潮的一套框架,但是需要有比较高的门槛。

下面我们来对比一下OkHttp网络请求和 retrofit网络请求的区别。

1. Okhttp请求总结

大家先看下面okhttp请求的样例代码:

代码语言:javascript复制
private void testOkHttp() throws IOException {
      //Step1
      final OkHttpClient client = new OkHttpClient();
      //Step2
      final Request request = new Request.Builder()
          .url("https://www.google.com.hk").build();
      //Step3
      Call call = client.newCall(request);
      //step4 发送网络请求,获取数据,进行后续处理
      call.enqueue(new Callback() {
          @Override
          public void onFailure(Call call, IOException e) {

          }

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

解析一下上面的代码:

Step1:创建HttpClient对象,也就是构建一个网络类型的实例,一般会将所有的网络请求使用同一个单例对象。

Step2:构建Request,也就是构建一个具体的网络请求对象,具体的请求url,请求头,请求体等等。

Step3:构建请求Call,也就是将具体的网络请求与执行请求的实体进行绑定,形成一个具体的正式的可执行实体。

Step4:后面就进行网络请求了,然后处理网络请求的数据了。

总结一下: OKhttp的意义:OkHttp是基于Http协议封装的一套请求客户端,虽然它也可以开线程,但根本上它更偏向真正的请求,跟HttpClient,HttpUrlConnection的职责是一样的。 OkHttp的职责:OkHttp主要负责socket部分的优化,比如多路复用,buffer缓存,数据压缩等等。

如果你想了解具体的OkHttp细节讲解,可以在文末寻找答案。

OkHttp给用户留下的问题

1)用户网络请求的接口配置繁琐,尤其是需要配置请求body,请求头,参数的时候;

2)数据解析过程需要用户手动拿到responsbody进行解析,不能复用;

3)无法适配自动进行线程的切换。

那么这几个问题谁来解决?对,retrofit!

2.Retrofit请求总结

Retrofit 进行网络请求的流程样板代码:

代码语言:javascript复制
//step1
Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://www.wanandroid.com/")
                .addConverterFactory(GsonConverterFactory.create(new Gson()))
                .build();
//step2
ISharedListService sharedListService =  retrofit.create(ISharedListService.class);
//step3
Call<SharedListBean> sharedListCall = sharedListService.getSharedList(2,1);
//step4
sharedListCall.enqueue(new Callback<SharedListBean>() {
     @Override
     public void onResponse(Call<SharedListBean> call, Response<SharedListBean> response{
         if (response.isSuccessful()) {
                 System.out.println(response.body().toString());
             }
         }

        @Override
        public void onFailure(Call<SharedListBean> call, Throwable t) {
           t.printStackTrace();
        }
});

Step1: 创建retrofit对象,构建一个网络请求的载体对象,和OkHttp构建OkhttpClient对象有一样的意义,只不过retrofit在build的时候有非常多的初始化内容,这些内容可以为后面网络请求提供准备,如准备 现成转换Executor,Gson convert,RxJavaCallAdapter。

Step2:Retrofit的精髓,为统一配置网络请求完成动态代理的设置。

Step3:构建具体网络请求对象Request(service),在这个阶段要完成的任务:

1)将接口中的注解翻译成对应的参数; 2)确定网络请求接口的返回值response类型以及对应的转换器; 3)将Okhttp的Request封装成为Retrofit的 OKhttpCall。

总结来说,就是根据请求service 的Interface来封装Okhttp请求Request。

Step4:后面就进行网络请求了,然后处理网络请求的数据了

总结一下

Retrofit主要负责应用层面的封装,就是说主要面向开发者,方便使用,比如请求参数,响应数据的处理,错误处理等等。

Retrofit封装了具体的请求,线程切换以及数据转换。

网上一般都推荐RxJava Retrofit OkHttp框架,Retrofit负责请求的数据和请求的结果,使用接口的方式呈现,OkHttp负责请求的过程,RxJava负责异步,各种线程之间的切换,用起来非常便利。

小结:

通过下图,让我们来总结一下,retrofit是如何来封装okhttp请求的。

大体的网络流程是一致的,毕竟都是通过OkHttp进行网络请求。

主要的步骤都是:

创建网络请求实体client -> 构建真正的网络请求 -> 将网络请求方案与真正的网络请求实体结合构成一个请求Call -> 执行网络请求 -> 处理返回数据 -> 处理Android 平台的线程问题。

在上图中,我们看到的对比最大的区别是什么?

1. OkHttp创建的是OkhttpClient,然而retrofit创建的是Retrofit实例 2. 构建蓝色的Requet的方案,retrofit是通过注解来进行的适配 3. 配置Call的过程中,retrofit是利用Adapter适配的Okhttp的Call 4. 相对okhttp,retrofit会对responseBody进行自动Gson解析 5. 相对okhttp,retrofit会自动的完成线程的切换。

具体的实现细节、设计模式、实现方案思路,我特地整理了一份《设计思想解读开源框架》给大家,带你深度分析OkHttp源码与Retrofit封装,梳理Retrofit的原理。

设计思想解读开源框架

第一章、热修复设计

第一节、AOT/JIT & dexopt 与 dex2oat 第二节、热修复设计之 CLASS_ISPREVERIFIED 问题 第三节、热修复设计之热修复原理 第四节、Tinker 的集成与使用(自动补丁包生成)

第二章、插件化框架设计

第一节、Class 文件与 Dex 文件的结构解读 第二节、Android 资源加载机制详解 第三节、四大组件调用原理 第四节、so 文件加载机制 第五节、Android 系统服务实现原理

第三章、组件化框架设计

第一节、阿里巴巴开源路由框——ARouter 原理分析 第二节、APT 编译时期自动生成代码&动态类加载 第三节、Java SPI 机制 第四节、AOP&IOC 第五节、手写组件化架构

第四章、图片加载框架

第一节、图片加载框架选型 第二节、Glide 原理分析 第三节、手写图片加载框架实战

今天的重点来了:

第五章、网络访问框架设计

第一节、网络通信必备基础 第二节、OkHttp 源码解读 第三节、Retrofit 源码解析

第六章、RXJava 响应式编程框架设计

第一节、链式调用 第二节、扩展的观察者模式 第三节、事件变换设计 第四节、Scheduler 线程控制

第七章、IOC 架构设计

第一节、依赖注入与控制反转 第二节、ButterKnife 原理 第三节、Dagger 架构设计核心解密

第八章、Android 架构组件 Jetpack

第一节、LiveData 原理 第二节、Navigation 如何解决 tabLayout 问题 第三节、ViewModel如何感知View生命周期及内核原理 第四节、Room 架构方式方法 第五节、dataBinding 为什么能够支持 MVVM 第六节、WorkManager 内核揭秘 第七节、Lifecycles 生命周期

OkHttp与Retrofit相关的面试题

来看看大厂面试中关于OkHttp与Retrofit面试官们都喜欢问些什么问题呢?

  • 你是怎么搭建Android应用框架的?
  • 责任链模式
  • interceptors和networkInterceptors的区别?
  • 设计模式和封层解耦的理念
  • 动态代理
  • .........

面试答案详细解析:

最后为了帮助大家深刻理解OkHttp与Retrofit相关知识点的原理以及面试相关知识,这里还为大家整理了Android开发相关源码精编解析

深入解析 Retrofit源码

深入解析OkHttp 源码

最后为了帮助大家深刻理解Android相关知识点的原理以及面试相关知识,这里放上我搜集整理的2019-2020BAT 面试真题解析,我把大厂面试中常被问到的技术点整理成了PDF,包知识脉络 诸多细节。

节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。

不用多说,相信大家都有一个共识:无论什么行业,最牛逼的人肯定是站在金字塔端的人。所以,想做一个牛逼的程序员,那么就要让自己站的更高,成为技术大牛并不是一朝一夕的事情,需要时间的沉淀和技术的积累。加油,共勉~

以上内容均免费分享给大家,需要完整版的朋友,点这里可以看到全部内容

0 人点赞