设计模式:

外观模式,构建者模式,工厂模式,代理模式,适配器模式,策略模式,观察者模式

Retrofit网络通信八步骤

  1. 创建Retrofit实例
  2. 定义网络请求接口,并为接口中的方法添加注解
  3. 通过动态代理生成网络请求对象
  4. 通过网络请求适配器将网络请求对象进行平台适配
  5. 通过网络请求执行器,发送网络请求(call)
  6. 通过数据解析器解析数据
  7. 通过回调执行器,切换线程
  8. 用户在主线程处理返回结果
@GET("/user/{user}/repos")
Call<ResponseBody> find(@Path("user") String user);//call封装了整个okhttp的请求Retrofit retrofit = new Retrofit.Builder().baseUrl("https://api.github.com/").addConverterFactory(GsonConverteractory.create())//.addCallAdapterFactory(RxJava2CallAdapterFactory.create()).build();//动态生成代理对象
Request req = retrofit.create(Request.class);
//生成一个OKHttpCall的代理对象
Call<ResponseBody> call = req.find(“Mike”);
//返回结果
Response<ResponseBody> response = call.execute();

先看Create方法

public <T> T create(final Class<T> service) {Utils.validateServiceInterface(service);if (validateEagerly) {eagerlyValidateMethods(service);}//重点看这里return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },new InvocationHandler() {private final Platform platform = Platform.get();@Override public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {// If the method is a method from Object then defer to normal invocation.if (method.getDeclaringClass() == Object.class) {return method.invoke(this, args);}if (platform.isDefaultMethod(method)) {return platform.invokeDefaultMethod(method, service, proxy, args);}ServiceMethod<Object, Object> serviceMethod =(ServiceMethod<Object, Object>) loadServiceMethod(method);OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);return serviceMethod.callAdapter.adapt(okHttpCall);}});
}

使用了动态代理,Proxy.newProxyInstance()返回一个代理类对象。

invoke方法接收三个参数,动态代理对象、我们调用的方法、参数数组;

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;
}

Build类:

public Builder(Retrofit retrofit, Method method) {this.retrofit = retrofit;this.method = method;// 获取 method 中的所有注解this.methodAnnotations = method.getAnnotations();// 获取 method 中方法的参数类型this.parameterTypes = method.getGenericParameterTypes();// 获得参数的值this.parameterAnnotationsArray = method.getParameterAnnotations();
}

build()方法主要内容

// 根据 retrofit 对象的 CallAdapterFactory 为 ServiceMethod 创建一个 callAdapter
callAdapter = createCallAdapter();
// 根据 retrofit 对象创建一个 responseConverter,默认是一个 BuildInConveter
responseConverter = createResponseConverter();
// 解析 method 的所有注解
for (Annotation annotation : methodAnnotations) {parseMethodAnnotation(annotation);
}

所以ServiceMethod主要封装了callAdapter和responseConverter ,对注解进行了解析,对后面网络请求做准备。

看回Create方法的代码

return serviceMethod.callAdapter.adapt(okHttpCall);

最后是调用了callAdapter的adapt方法,如果我们添加了RxJava2CallAdapter,

@Override
public Object adapt(Call<R> call) {Observable<Response<R>> responseObservable = isAsync? new CallEnqueueObservable<>(call): new CallExecuteObservable<>(call);Observable<?> observable;if (isResult) {observable = new ResultObservable<>(responseObservable);} else if (isBody) {observable = new BodyObservable<>(responseObservable);} else {observable = responseObservable;}if (scheduler != null) {observable = observable.subscribeOn(scheduler);}if (isFlowable) {return observable.toFlowable(BackpressureStrategy.LATEST);}if (isSingle) {return observable.singleOrError();}if (isMaybe) {return observable.singleElement();}if (isCompletable) {return observable.ignoreElements();}return observable;
}

所以如果添加了RxJava2CallAdapter就返回observal对象。

Retrofit中还有一个Converter ,与CallAdapter一样重要,用户可以根据需求对这两个进行自由扩展。

Okhttp中服务器返回的数据源就是ResponseBody对象。所以我们的目标就是对ResponseBody进行解析:

T convert(ResponseBody value){//do convert and return t
}

Retrofit不仅可以对ResponseBody进行转换,也可以对RequestBody进行转换;具体其内部提供了一个Convert.Factory:

abstract class Factory {//对ResponseBody进行数据转换的转换器public @Nullable Converter<ResponseBody, ?> responseBodyConverter(Type type,Annotation[] annotations, Retrofit retrofit) {return null;}//将未知数据转换成RequestBody的转换器public @Nullable Converter<?, RequestBody> requestBodyConverter(Type type,Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {return null;}//将未知数据转换成String类型的数据转换器public @Nullable Converter<?, String> stringConverter(Type type, Annotation[] annotations,Retrofit retrofit) {return null;}
}

开头构建Retrofit对象的

.addConverterFactory(GsonConverterFactory.create()) //添加Gson

就是用来添加Gson对象的

  public static GsonConverterFactory create() {return create(new Gson());}public static GsonConverterFactory create(Gson gson) {return new GsonConverterFactory(gson);}class GsonConverterFactory extends Converter.Factory{//持有一个gson对象用来讲原始数据转换成JavaBeanprivate final Gson gson;private GsonConverterFactory(Gson gson) {this.gson = gson;}}

具体转换过程可以看Gson原理分析。

Android—Retrofit解析相关推荐

  1. Android混淆解析

    此文章转载来源https://www.jianshu.com/p/84114b7feb38点击打开链接 Android混淆解析 一.混淆的目的 一款发布到市场的软件原则上都应该做代码混淆. 通过代码混 ...

  2. Android Retrofit 2.0文件上传

    Android Retrofit 实现(图文上传)文字(参数)和多张图片一起上传 使用Retrofit进行文件上传,肯定离不开Part & PartMap. public interface ...

  3. Android Retrofit 2.0(三)从源码分析原理

    Retrofit·特点 性能最好,处理最快 使用REST API时非常方便: 传输层默认就使用OkHttp: 支持NIO: 拥有出色的API文档和社区支持 速度上比volley更快: 如果你的应用程序 ...

  4. android json解析异常,json数据解析异常而导致网络请求失败的解决办法(其一)

    问题概述 笔者在开发过程中临时遇到一个本来仅有web端的项目临时增加Android端,导致后端在出接口时并未考虑Android端的json数据的解析,导致接口是这样的.... 正确请求 { " ...

  5. Android Retrofit+RxJava 优雅的处理服务器返回异常、错误

    Android Retrofit+RxJava 优雅的处理服务器返回异常.错误 参考文章: (1)Android Retrofit+RxJava 优雅的处理服务器返回异常.错误 (2)https:// ...

  6. Android Retrofit @Streaming 注解失效

    Android Retrofit @Streaming 注解失效 问题特征: 即使加了@Streaming方法也不能达到逐步加载大文件数据的效果,产生的效果为下载会有长时间的卡顿,卡顿后,会在极端的时 ...

  7. Android中解析XML

    Android中解析XML 转载于:https://www.cnblogs.com/zhujiabin/p/5868993.html

  8. android 如何实现无限列表,在Android中解析和创建无限/无限级别的List /子列表中的XML...

    在我的Android Application的服务器端应用程序也由我开发.在这个应用程序Android应用程序从服务器请求一些XML并解析它. XML包含描述应用程序中应该有多少标签的信息,并且每个标 ...

  9. 在linux kernel或android中解析cmdline参数

    文章目录 ★★★ 友情链接 : 个人博客导读首页-点击此处 ★★★ Kernel command line: earlycon androidboot.selinux=permissive uart_ ...

最新文章

  1. cron 工具 每分钟_计划任务 cron和crontab
  2. linux 命令行简介
  3. 皮一皮:精致的人生,哪怕拔火罐也要搭配衣服出门...
  4. 毕业论文 | 便携式环境烟雾监测器(源码、电路图)
  5. 理解有符号数和无符号数的区别
  6. windows 10下的kiosk模式
  7. greenplum 查询出来的数字加减日期_Python实践代码总结第5集(日期相关处理)
  8. Android Gradle和Gradle插件区别
  9. PyTorch 1.0 中文文档:数据类型信息
  10. 软件测试中有关界面测试经验总结
  11. python和c先学哪个-C和Python我该先学什么?
  12. C++程序设计方法3:类中的静态成员
  13. 黄淮学院计算机专业录取分数线2019,黄淮学院2020年录取分数线(附2017-2020年分数线)...
  14. paip.程序设计--扫号器跑号器结果分类设计
  15. python编一个答题程序_从0到1使用python开发一个半自动答题小程序的实现
  16. 利用matlab实现卷积实验报告,matlab卷积实验报告(共8篇).doc
  17. Python数据处理Tips数据重复值处理常用方法
  18. 云服务器wim7系统激活,云服务器怎么装win7系统教程
  19. IP-guard全部22个功能模块简介
  20. 喝酸奶竟然能预防霉菌性阴道炎

热门文章

  1. 初中计算机ppt教案,初中计算机ppt教案.doc
  2. 10G_Ethernet_04 10G Ethernet Subsystem IP 的快速验证(万兆以太网IP的快速验证)
  3. tp5分布式redis_TP5通过缓存数据到Redis
  4. cedit多行文本设置透明背景会重叠_PPT脱白教程11期【形状篇2】聊聊形状和文本框的那些事儿~...
  5. unity添加对象实例_【Unity】6.3 通过 C# 脚本创建和访问游戏对象
  6. ad20如何画出pcb板大小_多层pcb板是如何抄板的?
  7. 半导体芯片原厂涨价及调价声明新增了这些!
  8. 当电路与艺术相结合,美的让人窒息!
  9. 程序员崩溃的40个瞬间!(动图)
  10. java并发计数器_浅谈java并发之计数器CountDownLatch