Retrofit源码解析(一)

Retrofit源码解析(二)
Retrofit源码解析(三)
在介绍retrofit之前,还是要先详细说一下okhttp。retrofit与okhttp的角色关系就像包工头和工人,retrofit就是包工头,okhttp就是工人。当你想盖一栋房子(发送网络请求)的时候,你就要去和包工头协商我要什么样的房子(发送什么样的请求),当最终确定后,包工头就会派工人去进行实际施工(okhttp去完成实际的网络请求),房子竣工后包工头又来告诉你房子盖完了(retrofit的callback请求回调)。先来看用okhttp发送一个模拟的网络请求:

val okHttpClient = OkHttpClient.Builder().build()
val request = Request.Builder()
    .url("http://www.baidu.com/user/login")
    .get()
    .build()
val call = okHttpClient.newCall(request)
call.enqueue(object : Callback {

    override fun onResponse(call: Call, response: Response) {
        val responseBody = response.body()
        Log.d("请求成功", responseBody.string())
    }
    
    override fun onFailure(call: Call, e: IOException) {
        Log.d("", e.printStackTrace().toString())
    }

})

这里有几个比较重要的角色:okHttpClient、request、call、callback、response、responseBody

okhttpclient:用来创建call对象

request:封装了本次请求的参数信息,是Get还是Post方法等

call:最终由call发起网络请求

callback:okhttp网络请求的回调

response:一次网络请求的响应报文的封装类,例如包含响应header、body等

responseBody:一次网络请求的响应报文中,body的封装类。相当于下边报文中的Json部分

下边放上这次请求的响应报文:

GET /user/login HTTP/1.1
Host: www.baidu.com
Accept-Encoding: gzip
Connection: keep-alive

{
	"success": true,
	"name": "Tom"
}

最终通过responseBody.string()方法就拿到了一次网络请求最终返回的body的内容的字符串了,通常我们接口都会返回Json数格式的字符串数据,拿到这个数据,我们就可以使用Gson等库进行解析了。看到这里貌似okhttp很简单啊?的确,okhttp已经封装的很简单了,但是还不够优雅,例如okhttp没有做线程的切换,最终的callback是在工作线程完成的。并且每一次请求成功后我们都要自己手动去转换callback中返回的数据等等,所以retrofit就登场了。上边的请求再用retrofit写一遍:

interface Api {
    @GET("user/login")
    fun login(): Call<ResponseBody>
}


val retrofit = Retrofit.Builder().baseUrl("http://www.baidu.com/").build()
val api = retrofit.create(Api::class.java)
val call = api.login();
call.enqueue(object : retrofit2.Callback<ResponseBody> {
    override fun onResponse(call:retrofit2.Call<ResponseBody>,response: retrofit2.Response<ResponseBody>) {
        val responseBody = response.body()
        Log.d("请求成功", responseBody.string())
    }

    override fun onFailure(call: retrofit2.Call<ResponseBody>, t: Throwable) {
    
    }
})

和okhttp相比貌似retrofit也有两个相同的面孔:call、callback

call:在Api接口中,login方法的返回值是Call,这里的Call并不是okhttp中的Call

package okhttp3;
public interface Call extends Cloneable {
	···
}


package retrofit2;
public interface Call<T> extends Cloneable {
	···
}

可以看到retrofit并没有直接使用okhttp的Call类,而是自己又定义了一个带有泛型的Call<T>类。这里的泛型T就是最终callback的onResponse方法中返回数据的类型。 所以在默认情况下(没有为retrofit添加自定义的CallAdapterFactory,也没有添加ConverterFactory)时,Api接口中我们定义的方法必须返回 Call<ResponseBody> 类,否则会抛出异常,并且此时callback的onResponse方法中返回的类型就是Response<ResponseBody>类型的。但是这个我们后边再说。

callback:与call类似,retrofit同样定义了自己的callback类:

package okhttp3;
public interface Callback {
	···
}


package retrofit2;
public interface Callback<T> {
	···
}

上边的retrofit实现中,我们没有为retrofit设置GsonConverterFactory,所以此时retrofit并不具备自动将Json数据实例化的能力。所以在login方法中的返回值是Call<ResponseBody>,并且在最终callback的onResponse方法中得到了responseBody,这个ResponseBody类就是okhttp中的类,retrofit并没有再重新定义。所以最终的结果貌似和okhttp中是一样的都拿到了请求响应的ResponseBody,但其实不然,retrofit中callback的onResponse方法是执行在UI线程的,这里的线程转换是retrofit帮我们做的,至于是如何实现的后边再说。

总结

这篇文章对比了okhttp和默认的retrofit请求网络流程的大致区别,这只是一个开始,为后边retrofit的解析做铺垫,下一篇将解析retrofit的内部成员和功能。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值