Retrofit原理浅析
来源:互联网 发布:淘宝10元包邮入住 编辑:程序博客网 时间:2024/05/12 01:39
类库原理解析
注解
Retrofit使用注解+java接口来定义后台服务API接口
注解主要分为 方法注解 和 参数注解
注解 类型 作用 @GET方法注解表明HTTP请求方法为GET,(可选)注解的value属性用来设置相对/绝对url@POST方法注解表明HTTP请求方法为POST,(可选)注解的value属性用来设置相对/绝对url@PUT方法注解表明HTTP请求方法为PUT,(可选)注解的value属性用来设置相对/绝对url@DELETE方法注解表明http请求方法为DELETE,(可选)注解的value属性用来设置相对/绝对url@PATCH方法注解表明HTTP请求方法为PATCH,(可选)注解的value属性用来设置相对/绝对url@HEAD方法注解表明HTTP请求方法为HEAD,(可选)注解的value属性用来设置相对/绝对url@OPTIONS方法注解表明HTTP请求方法为OPTIONS,(可选)注解的value属性用来设置相对/绝对url@HTTP方法注解通过@HTTP注解指定http协议的请求方法,是否允许body,(可选)注解的value属性用来设置相对/绝对url@FormUrlEncoded方法注解表明发起HTTP请求的RequestBody是form表单方式@Multipart方法注解表明发起HTTP请求的RequestBody是Multipar方式@Headers方法注解使用注解的value值数组作为HTTP请求的头,用于一些固定的Header参数@Streaming方法注解用于需要直接返回流的函数@Url参数注解HTTP请求的url路径(相对/绝对),可以包含{path_holder},如:http://xxx.com/{user_holder}/detail@Path参数注解用于动态替换URL路径中的path_holder@Body参数注解表明此参数用作HTTP请求的body@Field参数注解表明此参数用作HTTP请求的form表单参数,key为注解的value值@FieldMap参数注解以map形式传入的form表单参数@Header参数注解表明此参数用作HTTP请求的header,key为注解的value值@HeaderMap参数注解以map形式传入的多个header键值对@Part参数注解表明参数为Http的multipart参数之一@PartMap参数注解以map形式传入的multipart参数表@Query参数注解GET方法的query参数,用于拼接完整请求路径@QueryMap参数注解以map传入的GET方法的query参数,用于拼接完整请求路径调用流程
通过上面代码可以看到调用关键的就是三步:
- 1 加载对应method的ServiceMethod实例
- 2 使用ServiceMethod实例和方法调用参数创建OkHttpCall
- 3 调用serviceMethod.callAdapter.adapt(okHttpCall)来产生method所定义的返回(Call<T>或者其他自定义CallAdapter支持的返回)
第一步、加载对应method的ServiceMethod实例
ServiceMethod中有以下四个变量比较重要
final okhttp3.Call.Factory callFactory;final CallAdapter<?> callAdapter;private final Converter<ResponseBody, T> responseConverter;private final ParameterHandler<?>[] parameterHandlers;
- callFactory是用来创建真正要执行的okhttp3.Call的工厂类,可以Retrofit.Builder中设置,如果不设置,默认会new一个OkHttpClient作为callFactory
- callAdapter是用来最终处理OkHttpCall实例并返回接口Method所定义的返回
- responseConverter 用来将Http请求的结果转换成接口Method所定义的结果(return或者Callback<T>中的T)
- parameterHandlers 根据接口Method参数的注解所生成的参数处理Handler数组
然后我们来看Retrofit.loadServiceMethod方法
ServiceMethod loadServiceMethod(Method method) { ServiceMethod result; synchronized (serviceMethodCache) { result = serviceMethodCache.get(method); if (result == null) { result = new ServiceMethod.Builder(this, method).build(); serviceMethodCache.put(method, result); } } return result; }
可以看到此处先检查serviceMethodCache是否有该method对应的ServiceMethod实例缓存,如果没有,则创建一个该method
对应的ServiceMethod实例并保存到缓存中。
ServiceMethod的创建使用的是建造者模式。
在ServiceMethod.Builder的build方法中,通过解析传入的method的方法定义(参数类型,返回类型,参数注解,方法注解)生成
对应的callAdapter,responseConverter,parameterHandlers及其他一些创建请求需要用到的信息。
public ServiceMethod build() { callAdapter = createCallAdapter(); ......检查返回结果类型...... responseConverter = createResponseConverter(); //生成方法注解的处理器 for (Annotation annotation : methodAnnotations) { parseMethodAnnotation(annotation); } .....方法与注解合法性检查..... int parameterCount = parameterAnnotationsArray.length; parameterHandlers = new ParameterHandler<?>[parameterCount]; for (int p = 0; p < parameterCount; p++) { .....注解合法性检查.... parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations); } ......方法与注解合法性检查...... return new ServiceMethod<>(this); }
此处在ServiceMethod.Builder.build()过程在生成过程中还会对method的定义做合法性检查,如:http方法是get就不允许方法参数中有body类型的参数;
方法为post则必须有参数为Body类型。
第二步、使用ServiceMethod实例和方法调用参数创建OkHttpCall
获取到method对应的ServiceMethod实例后,会使用该ServiceMethod实例和方法调用的参数Object... args生成一个OkHttpCall。
而OkHttpCall实际上是okhttp3.Call的一个包装类
,实际调用OkHttpCall的相关执行方法时最终是调用OkHttpCall内部用ServiceMethod.callFactory创建的okhttp3.Call来执行网络请求。
第三步、调用serviceMethod.callAdapter.adapt(okHttpCall)来产生method所定义的返回
Retrofit2默认支持的返回是返回一个Call<T>,利用此Call<T>实例可执行
Response<T> result = call.execute();//同步执行
或
//异步执行call.enqueue(new Callback(){ public void onResponse(Call<T> call, Response<T> response){ //TODO } public void onFailure(Call<T> call, Throwable t){ //TODO } });
其中在Android平台Retrofit2会自动使用主线程handler构造一个ExecutorCallAdapterFactory,调用enqueue(Callback),callback回调会在主线程中回调
另外在Retrofit的扩展Adapter中还提供了RxJavaCallAdapterFactory,Java8CallAdapterFactory,GuavaCallAdapterFactory
以RxJavaCallAdapterFactory为例,RxJavaCallAdapterFactory创建的callAdapter在执行adapt时将OkHttpCall包装一个Rx的Observable,在Observable被subscribe时才会真正的执行http请求。
- Retrofit原理浅析
- Retrofit原理浅析
- Retrofit原理浅析
- Retrofit原理浅析
- 解锁Retrofit -- 浅析Retrofit源码
- Retrofit源码浅析
- Retrofit浅析及使用
- Retrofit源码浅析
- retrofit之content-type浅析
- Retrofit原理简析
- Retrofit原理分析
- Retrofit简单原理分析
- Retrofit 原理 运行机制详解
- Retrofit 原理简析
- 非常火的retrofit+Rxjava浅析
- retrofit的实现原理(一)
- retrofit的实现原理(二)
- retrofit的实现原理(三)
- 一生之敌-2017浙江中医药大学程序设计
- 公众号门店列表管理,获取微信门店列表
- java计蒜客爬楼梯问题
- oracle 统计表中的字段数量
- android AudioTrack
- Retrofit原理浅析
- C++的构造函数属性初始化_静态成员_this指针
- 开始我的Go语言之旅
- 贝赛尔曲线 在线生成
- Python内置函数max()高级用法
- 《Java 编程技巧1001条》 第389条 了解不对称数组
- Spring框架
- 科学匠人 | 艾美工程奖背后的微软人
- 嵌入式 Linux 系统在线升级策略架构