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>() { @Override public void onResponse(Call<IpBean> call, Response<IpBean> response) { } @Override public void onFailure(Call<IpBean> call, Throwable t) { } });
Retrofit的创建
首先我们看看创建Retrofit时都做了哪些工作
public Retrofit build() { //这里可以看出我们必需设置baseUrl if (baseUrl == null) { throw new IllegalStateException("Base URL required."); } //如果我们没有设置自定义的OkHttpClient,就用默认的OkHttpClient okhttp3.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); //构建Retrofit return 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 { @Override public Executor defaultCallbackExecutor() { return new MainThreadExecutor(); } @Override CallAdapter.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()); @Override public 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是怎么利用适配器模式来为我们提供强大的灵活性的,敬请期待。
欢迎关注我的微信公众号,和我一起每天进步一点点!
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
AndroidStudio笔记(4)编码效率+1 的 File Templates
前言 这一篇是接着 AndroidStudio笔记(3)的,在上一篇中我们使用了 Live Templates的关键字来快速补全和生成代码,那有没有更近一步的骚操作?比如创建文件?答案是肯定的,那就是 File Templates。先看看今天的成果物预览图,如果不感兴趣就可以不看下去。 一键创建 TestViewPagerAdapter 创建TestViewPagerAdapter演示 创建RecyclerViewAdapter 创建RecyclerViewAdapter演示 正文 File Templates 的入口 File Templates 有两个入口。 File -> New -> Edit File Templates Edit File Templates File Templates Settings -> Editor -> File and Code Templates File and Code Templates 简单创建 ViewPagerAdapter File Templates 先来试试水,点击左上角的加号,新建一个模板,名字输入...
- 下一篇
微信跳一跳脚本重出江湖,python实现安卓&iOS自动版与手动版!
前面一段时间在GitHub上看到有人利用Python玩一款名为“跳一跳”的微信小程序,于是打算自己也来试一试,毕竟这款小游戏最近吸引了众多人的目光。 演示工具 电脑系统:Win10 Python版本:2.7.13(64位) 环境配置 Step1:安装Python 安装Python2.7并添加到环境变量中。 Step2:配置adb 将相关文件中提供的adb.zip文件解压,将解压后的文件夹添加到环境变量中。 (Win10系统:右键“此电脑”→“属性”→“高级系统设置”→“环境变量”→双击“Path”,将adb文件夹的路径添加进去即可。) 例如下图: 添加成功后在cmd窗口输入adb会有类似如下图所示的显示: Step3:安装依赖库 解压相关文件中提供的wechat_jump_game.rar文件。cmd窗口切换到解压后的文件夹内后输入pip install -r requirements.txt耐心等待相关依赖库安装完成即可。 如下图所示: 小编给大家推荐一个学习氛围超好的地方,python交流企鹅裙:【6.1.1,五三零,1.0.1】!适合在校大学生,小白,想转行,想通过这个找工作的加...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2整合Redis,开启缓存,提高访问速度
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- Hadoop3单机部署,实现最简伪集群
- CentOS7,CentOS8安装Elasticsearch6.8.6
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- CentOS7安装Docker,走上虚拟化容器引擎之路
- CentOS8编译安装MySQL8.0.19
- Docker安装Oracle12C,快速搭建Oracle学习环境