【一起学习开源框架】Retrofit相对于OKHttp,解决了什么问题

语言: CN / TW / HK

theme: channing-cyan highlight: androidstudio


前言

在学习完Retrofit后,相信大家都会思考一个问题,OkHttp作为一个关于网络请求的第三方类库,它已经是一种高内聚的,非常棒的关于网络请求方案具体的实现,而Retrofit的出现,它解决了OKhttp的哪些痛点呢?由于它本质网络请求还是依靠OKHttp来进行的,简单来说,Retrofit就是对OKHttp的封装,那么它封装的点是怎么解决OKHttp这些不友好的地方呢?下面我们就一起来探讨一下它们之前的联系吧

OKHttp流程概要

在讨论OKHttpRetrofit的关系之前,我们先来回顾下,OKHttp构建的流程吧,大致有以下四个步骤

  1. 构建OkHttpClient实例
  2. 构建Request,具体网络请求参数(地址,请求头等)
  3. 构建请求Call
  4. 服务器返回数据response

下面以OKHttp异步请求为例子: private fun asyRequest() {        //1.构建okhttpClient实例        val client = OkHttpClient.Builder().readTimeout(5, TimeUnit.SECONDS).build()        //2.构建Request,网络请求参数        val request = Request.Builder().url("https://www.baidu.com")           .get().build()        //3.构建请求call        val call = client.newCall(request)        //请求数据返回,手动切换请求适配器,手动切换线程        call.enqueue(object : Callback {            override fun onFailure(call: Call, e: IOException) {                println(e.message)           } ​            override fun onResponse(call: Call, response: Response) {                println(response.body().toString())           } ​       })   }

具体的结果response需要自己去解析,都是由用户自己去实现的,而OKHttp主要工作就是用来网络请求,也就是一种高内聚的,非常棒的关于网络请求方案具体的实现

okhttp流程.png

Retrofit相对于OKHttp所解决的问题

Retrofit的出现是为了更好的方便我们APP应用层来使用网络请求,解决OKHttp使用中存在的一些问题

OKHttp存在的缺陷

我们在使用OKHttp过程当中会存在以下缺陷

  • 客户端网络请求的接口配置比较繁琐,尤其是在需要配置复杂请求body,请求头,参数的时候
  • 数据解析过程中需要客户端手动拿到responseBody进行解析,而且还不能复用
  • 无法适配自动进行线程的切换
  • 万一我们存在嵌套网络请求就会陷入"回调陷阱"

所以为了解决以上问题,Retrofit就出现了,所以它并不是一个网络请求框架,准确来说,它就是一个RESTful风格的Http网络请求框架的封装,本质由OKHttp完成,而它仅仅负责网络请求接口的封装;

Retrofit出生开始就已经决定了它只是为了方便应用层来使用网络请求

  1. App应用层通过Retrofit去请求网络,实际上是使用Retrofit接口层封装请求参数,HeaderUrl等信息,这些不再需要我们手动去配置了,之后就是OKHttp来完成后续的操作
  2. 等到服务器返回数据之后,OKHttp将原始的数据结果交给Retrofit,然后它更具用户的需求对结果进行解析,这样基本解决了OKHttp中的无法自动进行数据解析和复用的问题了
  3. 总的来说,Retrofit优化了网络请求的使用,分别在创建网络请求的时候以及网络请求数据返回解析的时候,这样一来,图示就很明显了,如何去更好的创建Okhttp的网络请求Okhttp返回数据之后如何更好的去解析Retrofit基本上就解决了这两个问题

retrofit封装的点

我们已经知道Retrofit是为了解决OKHttp存在的问题而引申出来的,那么Retrofit针对这些问题时如何进行封装的呢?它封装的点是怎么样的,可以通过下面这张图直观感受到

  • Okhttp创建的是OKHttpClient,然而retrofit创建的是Retrofit实例
  • 构建蓝色的Request的方案,Retrofit是通过注解来进行适配
  • 配置Call的过程中,Retrofit是利用Adapter适配的OKHttpCall,为Call的适配提供了多样性,那么Retrofit可以支持Rxjava,这样一来就可以解决上面所提到的网络请求嵌套问题
  • 相对OKHttp,Retrofit会对responseBody进行自动的GSON解析,提供了可复用,易拓展的数据解析方案
  • 相对OKHttp,Retrofit会自动的完成线程的切换

RetrofitOKHttp的关系阐述

通过上面我们已经知道,Retrofit设计的任务主要就发生在OKHttp网络的请求前和请求后,下面我们就来看下请求前后Retrofit做了什么工作,如图所示

  1. 请求前主要做了两件事情: 统一配置网络请求头和一致适配请求Request,我们知道OKHttp实现的是Http协议,那么就有一定的规则,请求方法就只有八种(GET,POST,PUT,DELETE,PATCH,HEAD,OPTIONS,HTTP),既然都是符合Http协议的规则,那么就可以使用统一的规则来适配网络请求,这些在Retrofit里就是通过注解的形式,按照一定的策略来调配, 所以我们就把注解的解析过程看成一致适配请求Request
  2. 请求后也做了两件事情,就是将线程自动切换,数据自动适配成我们需要的java对象并且展示在UI线程

总体来说,我们知道了Retrofit在逐力解决上述这些问题,这也就是Retrofit的核心是用动态代理的原因了,因为请求前需要适配Request进行网络请求,而这个网络请求是由OKHttp这个委托者代理完成的,换句话说,Retrofit其实本身并不具备网络请求功能,它只是被OKHttp委托Retrofit对外进行网络请求,而Retrofit只是个代理,只是在网络请求前进行请求统一配置,请求之后进行数据处理,真正的网络请求依旧是OKHttp进行的;所以当问到Retrofit是如何进行网络请求的?回答只需要和OKHttp的一样就可以了