一、什么是 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 存在的问题
- 网络请求接口配置相对复杂,如果我们要配置复杂请求的 body 等参数,每次都得整一个 Request 等[当然可以抽取一个方法出来]
- 我们看到 enqueue 异步请求以后返回的 Response 我们需要拿到 body 体然后解析成我们所需要的数据
- 线程切换问题,我们知道 enqueue 是异步请求在子线程,回调 onResponse 和 onFailure 都是运行在子线程,我们的结果一般都是在 UI 线程展示,所以这里还需要线程切换
针对以上问题,同学们可能会说这个好办呀,我们把 OkHttp 封装一把加上泛型、handler 等方式不就可以解决以上问题吗,也就是分为三个部分:请求前、请求、请求后
- 请求前:处理请求参数配置等
- 让 OkHttp 去请求
- 把拿到请求的结果进行线程切换和反序列化[数据到 JavaBean 的映射]
这些问题人家人家 Square 公司也想到了,所以就开发了一个 Retrofit,大体思路也是这三个部分去进行处理的
1.2 什么是 Retrofit
什么是 RetorFit 呢?Retrofit 其实是一个 HTTP 的网络请求框架的封装,网络请求其实是由 OkHttp 完成的,而 Retrofit 仅负责网络请求接口的封装
App 应用程序通过 Retrofit 请求网络,实际上是使用 Retrofit 接口层封装请求参数、Header、Url 等信息,然后交给 OkHttp 完请求的操作,所以说 Retrofit 并不进行网络请求,真正的请求是 Okhttp 完成的
二、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?) {
// 失败的回调
}
})