博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
阅读:Retrofit 源码
阅读量:6324 次
发布时间:2019-06-22

本文共 4367 字,大约阅读时间需要 14 分钟。

Retofit入门使用

第一步:定义网络请求接口类

public interface MyApi {    @FormUrlEncoded    @POST    Call
getData(@Field("userId") String userId);}复制代码

第二步:初始化retrofit实例

Retrofit retrofit = new Retrofit.Builder()                .baseUrl("这里放基础url")                .build();复制代码

第三步:生成接口实现类

MyApi api = retrofit.create(MyApi.class);复制代码

第四步:调用接口方法,发起请求

Call
call = api.getData("1234");//post请求call.enqueue(new Callback
() { @Override public void onResponse(Call
call, Response
response) { } @Override public void onFailure(Call
call, Throwable t) { }});//get请求call.request();复制代码

至此,一个简单的使用retrofit网络请求完成。

推荐阅读

Retrofit 源码理解

知其然知其所以然,一起看看原理是怎么实现的。

Retrofit retrofit = new Retrofit.Builder()                .baseUrl("这里放基础url")                .build();复制代码

初始化分析-Builder()

创建了一个Builder对象,Buidler是Retrofit的静态内部类

Builder(Platform platform) {  this.platform = platform;}public Builder() {  this(Platform.get());}复制代码

这步很简单,初始化Builder对象,调用的无参构造,方法内部将 Platform.get() 作为参数又调用了自己的有参构造。

我们点开 Platform.get() 看看内部都做了什么 `

//静态常量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();}复制代码

这步就是根据不同的系统创建一个Platform对象,很显然我们是Android平台。

总结:这一步就是 通过Platform得到了一个Builder对象。

初始化分析-baseUrl()

/** * Set the API base URL. * * @see #baseUrl(HttpUrl) */public Builder baseUrl(String baseUrl) {  //判空  checkNotNull(baseUrl, "baseUrl == null");  //将字符串形式的地址 解析为 HttpUrl  HttpUrl httpUrl = HttpUrl.parse(baseUrl);  //判空呀  if (httpUrl == null) {    throw new IllegalArgumentException("Illegal URL: " + baseUrl);  }  return baseUrl(httpUrl);}//最终调用public Builder baseUrl(HttpUrl baseUrl) {  //判空  checkNotNull(baseUrl, "baseUrl == null");  //把地址 以“/”分割,放进集合,为了校验地址  List
pathSegments = baseUrl.pathSegments(); //校验地址不能以 “/”结尾 if (!"".equals(pathSegments.get(pathSegments.size() - 1))) { throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl); } this.baseUrl = baseUrl; return this;}复制代码

这一步就是对设置的baseUrl进行校验,最终输出一个HttpUrl类型的正确地址。

初始化分析-build()

public Retrofit build() {    //判空呀      if (baseUrl == null) {        throw new IllegalStateException("Base URL required.");      }    //okhttp的工厂实例 用于网络请求      okhttp3.Call.Factory callFactory = this.callFactory;      if (callFactory == null) {        callFactory = new OkHttpClient();      }      Executor callbackExecutor = this.callbackExecutor;      if (callbackExecutor == null) {        callbackExecutor = platform.defaultCallbackExecutor();      }      // Make a defensive copy of the adapters and add the default Call adapter.      List
callAdapterFactories = new ArrayList<>(this.callAdapterFactories); callAdapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor)); // Make a defensive copy of the converters. List
converterFactories = new ArrayList<>(1 + this.converterFactories.size()); // Add the built-in converter factory first. This prevents overriding its behavior but also // ensures correct behavior when using converters that consume all types. converterFactories.add(new BuiltInConverters()); converterFactories.addAll(this.converterFactories); return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories), unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly); }复制代码

这个方法,主要就是校对参数,baseUrl不可为空,callFactory就是okhttp的工厂实例,用于网络请求的,其他参数为空则创建,最终携带这些参数创建了一个Retrofit实例。

总结:以上就是 初始化阶段 的源码分析 ,比较简单,通过链式设置一系列参数,最终返回一个retrofit实例。

关键入口 create() 方法

接下来的部分,整个过程比较长,而且是关键部分,经过几番尝试,发现 流程图+文字分析 这种形式更加清晰。

  • 推荐阅读这篇文章

  • 参考流程图

总结

Retrofit在create方法中采用动态代理模式实现接口方法,这个过程构建了一个ServiceMethod对象,根据方法注解获取请求方式,参数类型和参数注解拼接请求的链接,当一切都准备好之后会把数据添加到Retrofit的RequestBuilder中。然后当我们主动发起网络请求的时候会调用okhttp发起网络请求,okhttp的配置包括请求方式,URL等在Retrofit的RequestBuilder的build()方法中实现,并发起真正的网络请求。

心得

  • 不必深究源码细节,不影响大流程的看不懂的直接跳过
  • 多看几遍,每多看一遍会发现其实还没弄懂
  • 参照别人的文章看完,要自己写写或者画画流程图

感谢

转载于:https://juejin.im/post/5cd24d56e51d453a363848e8

你可能感兴趣的文章
强制使用栅格图
查看>>
P1045 麦森数
查看>>
一个自动生成html的类
查看>>
Tomcat:Exception loading sessions from persistent storage
查看>>
servlets的表单提交响应
查看>>
C#中Main方法的四种形式
查看>>
Script:诊断SYSAUX表空间使用情况
查看>>
[Cocos2d-x For WP8]基础知识
查看>>
Android——Android Studio导入SlidingMenu类库的方法
查看>>
Jenkins+Maven+Sonar系统持续集成环境部署以及配置
查看>>
完美的nginx图片防盗链设置详解
查看>>
Windows下Redis的安装使用
查看>>
ASP.NET MVC中使用FluentValidation验证实体
查看>>
Python之模块和包学习
查看>>
C++11 多线程
查看>>
恢复低版本的FlashPlayer
查看>>
Opengl VS2008开发环境
查看>>
ylbtech-QQ(腾讯)-群空间-数据库设计
查看>>
面试书籍
查看>>
模式识别 - 处理多个演示样本研究(MIL)特点(matlab)
查看>>