Retrofit2源码解析(一)
本文基于Retrofit2的2.4.0版本
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
Retrofit2底层基于OkHttp3,是对利用OkHttp3请求网络的一种封装,可以使我们避免写很多重复的调用网络请求的代码,同时灵活性很高,可以定制自定义的OkHttpClient、自定义的数据解析转换器(比如Gson、Jackson等)、自定义的请求转换器(比如结合RxJava)。
Retrofit2的另一个特点就是使用运行时注解,我们在使用时可以根据需要来利用注解将我们的业务调用接口转换成Http请求的接口。
下面先来看看我们使用Retrofit2发起网络请求的步骤
(1)创建我们的具体业务接口,这里比如我们调用淘宝的IP地址库
public interface MyService {@GET("getIpInfo.php=11.11.11.11")Call<IpBean> getData();
}
(2)创建Retrofit
retrofit = new Retrofit.Builder().baseUrl("https://ip.taobao.com/service/").addConverterFactory(GsonConverterFactory.create()).build();
可见Retrofit2采用的是Builder模式来构建的
(3)利用Retrofit创建我们的接口对象,生成Call对象,并调用请求网络方法
MyService myService = retrofit.create(MyService.class);
Call<IpBean> call = myService.getData();
call.enqueue(new Callback<IpBean>() {@Overridepublic void onResponse(Call<IpBean> call, Response<IpBean> response) {}@Overridepublic void onFailure(Call<IpBean> call, Throwable t) {}
});
Retrofit的创建
首先我们看看创建Retrofit时都做了哪些工作
public Retrofit build() {//这里可以看出我们必需设置baseUrlif (baseUrl == null) {throw new IllegalStateException("Base URL required.");}//如果我们没有设置自定义的OkHttpClient,就用默认的OkHttpClientokhttp3.Call.Factory callFactory = this.callFactory;if (callFactory == null) {callFactory = new OkHttpClient();}//这个callbackExecutor用于回调到UI线程Executor callbackExecutor = this.callbackExecutor;if (callbackExecutor == null) {callbackExecutor = platform.defaultCallbackExecutor();}//将我们设置的Call适配器添加到列表中,比如RxJava的适配器List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);//添加默认的Call适配器callAdapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));// Make a defensive copy of the converters.List<Converter.Factory> converterFactories =new ArrayList<>(1 + this.converterFactories.size());//添加数据转换器,用于将网络请求返回的结果转换成我们需要的类型converterFactories.add(new BuiltInConverters());converterFactories.addAll(this.converterFactories);//构建Retrofitreturn new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
}
通过上面Retrofit2的Builder的build方法,我们可以看出在Retrofit2中主要有这么几个部分:
(1)用于执行具体网络请求的callFactory,也就是OkHttpClient。所以说Retrofit2是基于OkHttp3的封装。
(2)callbackExecutor回调执行器,这个是用于网络请求返回后回调到主线程的。我们知道,在利用OkHttp3进行网络请求时,我们需要手动回调到主线程,以便更新UI。那我们来看看这个默认的defaultCallbackExecutor是不是这样。
//Retrofit.class
public Builder() {this(Platform.get());
}Builder(Platform platform) {this.platform = platform;
}
可以看到在Builder中调用的是Platform的get方法,返回对应的平台,然后在build方法里通过platform的defaultCallbackExecutor得到我们的回调器。下面我们看看这个Platform类
class Platform {private static final Platform PLATFORM = findPlatform();static Platform get() {return PLATFORM;}private static Platform findPlatform() {try {Class.forName("android.os.Build");if (Build.VERSION.SDK_INT != 0) {return new Android();}} catch (ClassNotFoundException ignored) {}try {Class.forName("java.util.Optional");return new Java8();} catch (ClassNotFoundException ignored) {}return new Platform();}...static class Android extends Platform {@Overridepublic Executor defaultCallbackExecutor() {return new MainThreadExecutor();}@OverrideCallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {if (callbackExecutor == null) throw new AssertionError();return new ExecutorCallAdapterFactory(callbackExecutor);}static class MainThreadExecutor implements Executor {private final Handler handler = new Handler(Looper.getMainLooper());@Overridepublic void execute(Runnable r) {handler.post(r);}}}
}
从上面的源码中我们可以看到Platform中会根据当前运行的平台返回不同的子类,这里当然就是Android这个内部类了。所以当我们调用platform的defaultCallbackExecutor时,实际上调用的是Android这个类的defaultCallbackExecutor方法,而这个方法返回的是MainThreadExecutor,它的作用就是利用handler将执行结果回调到主线程中。
(3)callAdapterFactories适配器列表,这里面存放的是所有的Call适配器CallAdapter。这个CallAdapter是干嘛的呢?我们知道Retrofit2底层是用Okhttp3来请求网络的,那势必是通过OkHttp3的Call来执行请求,但是我们在实际使用Retrofit2时,可能需要结合请他的三方库,常见的比如RxJava,那我们接口中所需要返回的可能就是Observable而不是Call了。
@GET("getIpInfo.php?ip=11.11.11.11")
Observable<IpBean> getObservableData();
所以Retrofit2就需要一个Call适配器CallAdapter,来将Call转换为我们需要的Observable,这就是CallAdapter的作用。
(4)converterFactories返回结果转换器列表,这里面存放的是将网络返回结果,也就是OkHttp3返回的Response,解析转换成我们需要的实际类型,比如IpBean实体类。如GsonConverterFactory就是一个常用的转换器,相当于Retrofit2把我们直接使用Okhttp3来请求网络数据时需要将返回结果进行Gson解析的动作也替我们做了。
总结
(1)这里我们简单分析了Retrofit的创建过程,可以发现Retrofit中核心部分包括OkHttpClient、Call适配器、Response转换器以及用于将请求回调到UI线程的回调执行器等。
(2)Retrofit的创建采用的是Builder模式,定制化程度很高,我们可以设置自己的OkHttpClient,也可以实现自定义的Call适配器和Response转换器,以及请求的回调执行器。
(3)可见Retrofit虽然做了很大程度的封装,但是灵活性扩展性依然很高,我们几乎可以扩展更改网络请求的大部分过程。
今天我们先浅尝则止,后面我们再来具体分析下Retrofit2的网络调用过程,看看Retrofit2是怎么利用适配器模式来为我们提供强大的灵活性的,敬请期待。
欢迎关注我的微信公众号,和我一起每天进步一点点!
Retrofit2源码解析(一)相关推荐
- Retrofit2源码解析——网络调用流程(下)
Retrofit2源码解析系列 Retrofit2源码解析(一) Retrofit2源码解析--网络调用流程(上) 本文基于Retrofit2的2.4.0版本 implementation 'com. ...
- Retrofit2源码解析
一.前言: Retrofit: 一个 Restful 设计风格的 HTTP 网络请求框架的封装.基于 OkHttp 严格地说,Retrofit2并不是一个网络请求交易框架,它只是对网络请求框架的封装. ...
- Retrofit2 源码解析
Retrofit是什么 简单的说它是一个基于OkHttp的RESTFUL Api请求工具,从功能上来说和Google的Volley功能上很相似,但是使用上很不相似. Retrofit怎么用 比如你要请 ...
- Retrofit2 源码解析之动态代理
基于 Retrofit 2.3.0 & Android 8.1 分析 Java 动态代理在 Android 上的实现 未经允许不得转载 Retrofit 使用示例 public interfa ...
- Java生鲜电商平台-SpringCloud微服务架构中网络请求性能优化与源码解析
Java生鲜电商平台-SpringCloud微服务架构中网络请求性能优化与源码解析 说明:Java生鲜电商平台中,由于服务进行了拆分,很多的业务服务导致了请求的网络延迟与性能消耗,对应的这些问题,我们 ...
- Retrofit2源码分析(一)
本文将顺着构建请求对象→构建请求接口→发起同步/异步请求的流程,分析retrofit2是如何实现的. 组成部分 Retrofit2源码主要分为以下几个部分: retrofit retrofit-ada ...
- Retrofit源码解析
本文分析的源码基于retrofit:2.9.0. 前言 Retrofit基于OkHttp,网络请求的工作本质上是 OkHttp 完成,而 Retrofit 仅负责 网络请求接口的封装,它们的关系示意图 ...
- Retrofit 源码解析(2.9.0 版本)
文章目录 1.简介 2.Retrofit 配置与基本用法 2.1 依赖引入与配置 2.2 基本用法 3.Retrofit 的注解 3.1 请求方法注解 3.2 请求头注解 3.3 请求参数注解 3.4 ...
- 谷歌BERT预训练源码解析(二):模型构建
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/weixin_39470744/arti ...
最新文章
- htc one m7刷Linux,HTC One M7刷机教程 HTC One M7线刷教程
- python并发发送http请求_用python异步发送http请求来提升效率
- C# Excel转换为Json
- how can you save more space at home?
- SQL语句:SQLwhile(0=0)与while @@fetch_status=0.
- 【MyBatis】MyBatis分页插件PageHelper的使用
- 调试实战 —— dll 加载失败之 Debug Release争锋篇
- PAT (Basic Level) Practice (中文)1041 考试座位号 (15 分)
- 电子信息计算机调剂到能源动力,江苏科技大学机械、电子信息、电子信息能源动力、土木水利2020年考研调剂信息...
- Docker容器实战(七) - 容器中进程视野下的文件系统
- 【目瞪口呆】通信机房内部长这样
- LC5软件破解用户口令
- win32asm写的红警2的修改器
- html css remove,CSS類別操作--.removeClass()
- PowerPoint.Application win32 操作ppt 复制 新建 插入图片
- Hyperledger fabric-couchdb镜像版本的坑
- Transformers库pipeline API的使用
- java JFreechart开发报表的实例demo下载
- PyCharm Plugins
- 使用hexo搭建一个博客超详细步骤
热门文章
- 项目管理文档_项目管理和团队协同的轻量级工具——PMS,来了
- 熊乃学 计算机,信息工程学院 - 副本.pdf
- spring 字面值 特殊字符 配置使用
- mysql中delete,truncate,drop区别
- linux安装运行jmeter,Linux下安装运行Jmeter程序
- apache php提示下载,apache正在下载php文件而不是显示它们。
- bat 复制文件夹_新建366个文件夹,你用了2小时,我使用excel与bat命令1分钟搞定...
- linux关机_LINUX快速入门第二章:Linux 系统启动过程
- mysql where执行顺序_mysql where执行顺序
- ultraedit比较文件没反应_计算机二级虚拟机安装视频和虚拟机文件