Retrofit作为当下Android开发最流行的网络请求框架之一,基于上一篇《展开说说Android之Retrofit详解_使用篇》本文继续分析一下Retrofit的源码实现。
对我个人来说学习一个新事物,一般是三个步骤:做什么、怎么用、为什么。做什么的大家已经明了要不然也不会点开看、怎么用上一篇已经分析了,至于“为什么” 本文将从以下几个角度分析Retrofit源码:
A、Retrofit框架有哪些核心类和接口
B、@GET、@POST等这些注解的作用
C、听说Retrofit是封装的Okhttp,源码中怎么实现的呢
D、为什么OKHttp异步请求是在子线程返回但Retroift却可以在主线程返回
E、梳理一下我们发起请求时的完整流程
F、最后简单总结一下Retrofit的优缺点
- Retrofit框架有哪些核心类和接口
1、Retrofit类
作为框架的入口点,结构和OKHttpClient类似,也有一个一个Builder内部类,Builerd提供了包括设置基础URL、转换器工厂、调用适配器等核心组件,还有一个熟悉的build方法用来创建Retrofit实例。他还有一个非常重要的方法create,是负责创建请求对象的。
2、ServiceMethod类
解析接口方法的注解信息(如@GET、@POST等),创建请求对象,最后把方法参数转换为发送HTTP请求携带的参数。
它是个抽象类,只有一个普通方法parseAnnotations负责解析注解并创建请求对象,负责准备工作,二另一个invoke却是个抽象方法,它时我们发起请求的核心方法。
3、RequestFactory类
其实这个才是真正解析注解并创建请求对象的,ServiceMethod的parseAnnotations方法就是调用了RequestFactory的同名方法parseAnnotations完成的实际工作。还能动态生成HTTP请求的URL、Header和Body等.
4、HttpServiceMethod
第二点提到ServiceMethod的抽象方法invoke,它的实现是在子类HttpServiceMethod中。这里invoke方法会创建另一个核心类OkHttpCall。
5、各个注解类(如@GET、@POST、@Query等)
我们知道使用Retrofit肯定离不开注解的使用,每个注解就是一个类,定义API请求的元数据,他们包括请求方法、路径、参数等,极大的简化HTTP请求的配置。他们都是再http目录下,数量很多,截图为一部份:

6、OkHttpCall类
它封装OkHttp了Call对象,负责Retrofit与OkHttp之间的交互,这里会调用OKHttp的enqueue和execute执行网络请求然后将返回报文给到Retrofit的回调方法最终给到调用者来处理响应。
7、Converter接口及其实现类
负责对请求/响应数据的序列化与反序列化,例如将JSON响应转换为Java对象。一般用Gson或、Moshi。
5、Response类
封装服务器返回的原始响应数据,包括状态码、响应头和响应体。
二、@GET、@POST等这些注解的作用
Retrofit的注解一般分为三种种,用于定义网络请求类型和配置请求参数以及拥有特定技能的注解:
- 定义网络请求类型的
包括@GET、@POST、@PUT、@DELETE等,就是我们常用的接口请求类型。
- 定义请求参数的注解:
@Path 动态替换URL路径中的占位符(如users/{index}中的{index})。
@Query:添加单个查询参数(如?key=value)
@QueryMap:以Map形式添加多个查询参数。
@Field/@FieldMap二者都用于表单提交,自动进行URL编码,@Field("key")用绑定单个字段、@FieldMap Map<String, String>则用于绑定多个字段。
@Body 直接序列化对象为请求体(如JSON),需配合Gson或Moshi转换器。
- 用特定技能的注解
@Url动态指定完整请求URL,覆盖Retrofit实例设置的全局的baseUrl。
@Headers:静态添加请求头(如@Headers("Cache-Control: max-age=3600"))
@Header:动态添加请求头(通过方法参数传入)。
@Multipart 用于文件上传,需配合@Part或@PartMap声明分块数据。
@Streaming 标记响应体以流式处理,适用于大文件下载。
三、听说Retrofit是封装的Okhttp,源码中怎么实现的呢
就是上面第一部分第6点中提到的OkHttpCall,它封装OkHttp了Call对象,负责Retrofit与OkHttp之间的交互,这里会调用OKHttp的enqueue和execute执行网络请求然后将返回报文给到Retrofit的回调方法最终给到调用者来处理响应。
1、先看它的导包:

2、以enqueue方法为例:

上面可以看出,OkHttpCall中enqueue方法会调用OKHttp的enqueue方法,这块跟咱们自己使用OKHttp一样的,不过这里是又多经历了一层Retrofit的回到才给到调用者。
四、为什么OKHttp异步请求是在子线程返回但Retroift却可以在主线程返回
Retrofit中有个Platform类,他有一个内部类Android,也是它的子类。 Android类中有一个MainThreadExecutor类继承Executor,并且它内部有一个使用Looper.getMainLooper()创建的Handler,看完这里就直到为啥再主线程返回了吧。

五、梳理一下我们发起请求时的完整流程
public <T> T getServer(Class<T> cls, String baseUrl){
if (retrofit == null){
retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.client(getClient())
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit.create(cls);
}
以此为例,这段完整代码,再上一篇文章已经提供:
上面提到Retrofit也是建造者模式,他也有内部类Builder。
1、Retrofit.Builder()会创建一个PlatForm对象。
2、baseUrl(baseUrl) 设置请求接口的公共Url
/**
* Set the API base URL.
* @see #baseUrl(HttpUrl)
*/
public Builder baseUrl(String baseUrl) {
Objects.requireNonNull(baseUrl, "baseUrl == null");
return baseUrl(HttpUrl.get(baseUrl));
}
3、.client(getClient()) 用来设置OkhttpClient。
注:设置超时时间、拦截器、cookie等都是这个Okhttpclient对象中。
* The HTTP client used for requests.
*
* <p>This is a convenience method for calling {@link #callFactory}.
*/
public Builder client(OkHttpClient client) {
return callFactory(Objects.requireNonNull(client, "client == null"));
}
4、addConverterFactory设置转换器
5、build()建造者模式,构建Retrofit对象

7、非常非常重要的一个方法,create

这里用到了动态代理Proxy.newProxyInstance,在你用create方法构建的请求对象调用接口后回调InvocationHandler的invoke方法。然后我们呢顺着捋一捋你发起请求后的流程,从loadServiceMethod(method).invoke(args)开始:

他会调用ServiceMethod的parseAnnotations方法,之前提到过的parseAnnotations
方法和抽象方法invoke:

RequestFactory也是建造者模式,有个Builder内部类,其内部也有build方法 它回调用parseMethodAnnotation方法解析我们设置的注解。

最终return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
返回CallAdapted对象,而CallAdapted的父类是HttpServiceMethod,HttpServiceMethod的父类是ServiceMethod。
HttpServiceMethod中createCallAdapter方法,然后到Retrofit的callAdapter
方法,再调用nextCallAdapter方法,然后这一行CallAdapter<?, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this);到了DefaultCallAdapterFactory类的get方法:

再回到loadServiceMethod(method).invoke(args)的后半部分,invoke(args),他调用的是ServiceMethod中抽象方法invoke的实现类重写的invoke方法就是上面get方法中new CallAdapter时重写的方法。

记住这个executor就是Platform类中Android类的MainThreadExecutor的对象,它是callbackExecutor赋值的,而callbackExecutor时再Retrofit的build方法时传过来的。
当CompletableFutureCallAdapterFactory中触发adapter时。

然后也是抽象方法adapt,再到实现类DefaultCallAdapterFactory
中enqueue方法:

最后callbackExecutor.enqueue方法又回到了,MainThreadExecutor
的execute方法,因此在主线程给开发者返回了报文。

想了解Retrofit使用的朋友可以参考上一篇《展开说说Android之Retrofit详解_使用篇》。
个人总结记录,才疏学浅,如有错误,欢迎指正,多谢。

3489

被折叠的 条评论
为什么被折叠?



