01、捣鼓源码-Retrofit2.x


一、什么是 Retrofit

1.1 为什么要有 Retrofit

Square 公司出了一个基于 HTTP 的网络请求框架 Okhttp,可以帮助我们快速处理 HTTP 的请求,但是这个框架存在一些问题,虽然已经很大程序上简化了开发者的使用,但是使用起来还不是非常的方便,如果想要很方便的使用必须要对其进行封装。

先来看一看 Okhttp 的使用方式

Okhttp 的使用方式

private fun fetchApi() {

    // 1、初始化 OkhttpClient
    val client: OkHttpClient = OkHttpClient()

    // 2、构建请求体
    val request: Request = Request.Builder()
        .url("https://www.wanandroid.com/banner/json")
        .build()

    // 3、创建 Call 对象
    val call: Call = client.newCall(request)

    // 4、发起异步请求,运行在子线程
    call.enqueue(object : Callback {
        override fun onFailure(call: Call?, e: IOException?) {
            // 运行在子线程
            println("请求失败") 
        }

        override fun onResponse(call: Call?, response: Response?) {
            // 运行在子线程
            val body = response?.body()
            body?.let {
                println("请求成功:结果 \n ${it.string()}")
            }
        }
    })
}

以上就是基本使用 OkHttp 的方式,但是如果我们每个请求都这样去写,会有大量的重复代码,并且没有扩展性,我们说一下 OkHttp 的使用的问题

OkHttp 的请求流程

OkHttp请求流程

以上就是 OkHttp 的一个基本的流程

Okhttp 存在的问题

  • 网络请求接口配置相对复杂,如果我们要配置复杂请求的 body 等参数,每次都得整一个 Request 等[当然可以抽取一个方法出来]
  • 我们看到 enqueue 异步请求以后返回的 Response 我们需要拿到 body 体然后解析成我们所需要的数据
  • 线程切换问题,我们知道 enqueue 是异步请求在子线程,回调 onResponse 和 onFailure 都是运行在子线程,我们的结果一般都是在 UI 线程展示,所以这里还需要线程切换

针对以上问题,同学们可能会说这个好办呀,我们把 OkHttp 封装一把加上泛型、handler 等方式不就可以解决以上问题吗,也就是分为三个部分:请求前、请求、请求后

  • 请求前:处理请求参数配置等
  • 让 OkHttp 去请求
  • 把拿到请求的结果进行线程切换和反序列化[数据到 JavaBean 的映射]

封装 OkHttp

这些问题人家人家 Square 公司也想到了,所以就开发了一个 Retrofit,大体思路也是这三个部分去进行处理的

1.2 什么是 Retrofit

什么是 RetorFit 呢?Retrofit 其实是一个 HTTP 的网络请求框架的封装,网络请求其实是由 OkHttp 完成的,而 Retrofit 仅负责网络请求接口的封装

App 应用程序通过 Retrofit 请求网络,实际上是使用 Retrofit 接口层封装请求参数、Header、Url 等信息,然后交给 OkHttp 完请求的操作,所以说 Retrofit 并不进行网络请求,真正的请求是 Okhttp 完成的

二、Retrofit 的流程

俗话说无图无真相,先来一幅图

Retrofit请求流程

Retrofit 内部使用了大量的设计模式来进行功能模块的解耦

2.1 Retrofit 简单的使用

简单的过一下 Retorfit 的使用,举个例子

先声明一些数据对象和服务类

// WanAndroidService.kt
interface WanAndroidService {

    @GET("banner/json")
    fun getBanners(): Call<ApiResponseData<List<Banner>>>
}
// ApiResponseData.kt
data class ApiResponseData<T> (
    val data:T,
    val errorCode: Int,
    val errorMsg:String
)

// Banner.kt
data class Banner(
    val desc:String,
    val id:Int,
    val imagePath:String,
    val url:String,
    val title:String,
    val order:Int,
    val type:Int
)

使用 retrofit 四步法:

// 第一步声明 retrofit
val retrofit = Retrofit.Builder()
            .baseUrl("https://www.wanandroid.com/")
            .addConverterFactory(GsonConverterFactory.create())
                        .build()

// 第二步取得请求服务,参数地址等
val service = retrofit.create(WanAndroidService::class)

// 第三步 生成 Call
val banners = service.getBanners()

// 第四步、异步执行请求
banners.enqueue(object : Callback<ApiResponseData<List<Banner>>> {
        override fun onResponse(
            call: Call<ApiResponseData<List<Banner>>>?,
            response: Response<ApiResponseData<List<Banner>>>?,
        ) {
            // 成功的回调
            response?.body()?.let {
                val data = it.data
                println(data)
            }
        }

        override fun onFailure(call: Call<ApiResponseData<List<Banner>>>?, t: Throwable?) {
          // 失败的回调
        }

    })

三、Retrofit 源码解析


交个朋友

如果觉得本篇对你有帮助,那么请你完成以下几件小事情

1、动动你的小手关注一下以下公众号「TigerChain」查看更多精彩分享

2、更多视频关注的我的 B站:https://space.bilibili.com/44242327/


文章作者: TigerChain
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 TigerChain !
评论
  目录