作为一个coder 最悲哀的莫过于知其然,不知其所以然。

闲暇之余,研究研究Retrofit源码,为了防止大篇幅的代码,看得头晕眼花,这章仅仅详细介绍Retrofit 的创建过程。Retrofit使用方法这里就不介绍了,请看我前面写的博客。

首先贴上需要提前展示的APIService:

public interface UserService {@POST(Constants.URL_UPDATE_USER_LIST)Observable<BaseResponse<List<User>>> updateUserList(@Query("userList") String userList);
}
Retrofit retrofit = new Retrofit.Builder().baseUrl(getEndPoint(t)).addConverterFactory(GsonConverterFactory.create()).addCallAdapterFactory(RxJavaCallAdapterFactory.create()).client(clientBuilder.build()).build();
service = retrofit.create(t);

如上所述使用retrofit 访问网络就是这么简单,那么Retrofit框架怎样实现的呢?请往下看

Retrofit类有一个静态内部类Builder,调用Builder的build()方法就能生成Retrofit对象,看看它的成员变量,是不是觉得网络访问的几要素都具备了?

网络请求工具、线程处理工具、网络访问回调处理工具、网络访问结果解析工具。

public static final class Builder {private Platform platform;
  private okhttp3.Call.Factory callFactory;
  private HttpUrl baseUrl;
  private List<Converter.Factory> converterFactories = new ArrayList<>();
  private List<CallAdapter.Factory> adapterFactories = new ArrayList<>();
  private Executor callbackExecutor;
  private boolean validateEagerly;

  Builder(Platform platform) {this.platform = platform;
    // 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());
  }public Builder() {this(Platform.get());
  }

首先来看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) {}try {Class.forName("org.robovm.apple.foundation.NSObject");
      return new IOS();
    } catch (ClassNotFoundException ignored) {}return new Platform();
  }

第一个默认就是查找是否是Andriod平台,当然后面还有Java8,IOS的Platform,有兴趣可以查看源码,先来看看Android:

static class Android extends Platform {@Override public Executor defaultCallbackExecutor() {return new MainThreadExecutor();
  }@Override CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {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);
    }}
}

是不是看到熟悉的东西了,没错,它就是Handler,现在是不是觉得Retrofit底层也是利用了Handler?

仔细查看相关源码就能得出以下描述:

调用默认的Retrofit.Builder()方法默认会自动判断platform为Andriod,然后赋值给Retrofit.Builder类的platform变量。

.baseUrl(String url)方法解析我们传入的url参数生成一个HttpUrl对象存放于Retrofit. Builder类的成员变量baseUrl中。

.addConverterFactory方法添加相应结果解析器,存放于Retrofit.Builder类的converterFactories集合中。从Builder的构造方法可以看出创建Builder的时候会自动添加一个默认的ConvertFactory,我们也可以调用多次addConverterFactory添加多个ConvertFactory,处理结果的时候会按添加顺序优先匹配,一旦匹配上前面的,就丢弃后面的,当然我们能添加自己定义的ConvertFactory只要继承Converter.Factory,详细放在后面讲解。

.addCallAdapterFactory方法添加访问处理适配器,存放于Retrofit.Builder类的adapterFactories集合中。

.client方法用于添加网络访问工具OKHttpClient,保存在Retrofit.Builder类的callFactory变量中.

调用.build()方法,通过platform设置Retrofit.Builder类的callbackExcutor变量,然后最终会生成一个Retrofit对象。

public Retrofit build() {if (baseUrl == null) {throw new IllegalStateException("Base URL required.");
  }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<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);
  adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));

  // Make a defensive copy of the converters.
  List<Converter.Factory> converterFactories = new ArrayList<>(this.converterFactories);

  return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,
      callbackExecutor, validateEagerly);
}

再来看看Retrofit的成员变量和构造方法:

public final class Retrofit {private final Map<Method, ServiceMethod> serviceMethodCache = new LinkedHashMap<>();

  private final okhttp3.Call.Factory callFactory;
  private final HttpUrl baseUrl;
  private final List<Converter.Factory> converterFactories;
  private final List<CallAdapter.Factory> adapterFactories;
  private final Executor callbackExecutor;
  private final boolean validateEagerly;

  Retrofit(okhttp3.Call.Factory callFactory, HttpUrl baseUrl,
      List<Converter.Factory> converterFactories, List<CallAdapter.Factory> adapterFactories,
      Executor callbackExecutor, boolean validateEagerly) {this.callFactory = callFactory;
    this.baseUrl = baseUrl;
    this.converterFactories = unmodifiableList(converterFactories); // Defensive copy at call site.
    this.adapterFactories = unmodifiableList(adapterFactories); // Defensive copy at call site.
    this.callbackExecutor = callbackExecutor;
    this.validateEagerly = validateEagerly;
  }

这就像是将它的静态内部类Builder里的成员变量搬过来的。serviceMethodCache是一个存储方法(当然是我们定义在接口里的方法啦)Map,后面会用到。

到这里Retrofit总算是被我们给new出来了,下一章就该讲解我们需要的Api Service的创建以及访问了。

Retrofit详解(一)(Retrofit创建过程)相关推荐

  1. Retrofit详解(二)(Retrofit核心流程)

    上一章已经介绍了Retrofit创建过程,这章介绍Retrofit Api Service创建与访问过程. Retrofit 相比Volley等网络框架一个最大区别就是它只需要声明接口,就可以访问网络 ...

  2. 多图详解freeBSD8.2安装过程

    多图详解freeBSD8.2安装过程 Wmware新建freeBSD虚拟机,光盘挂载freeBSD.iso.真机光驱放freeBSD光盘,修改bios光驱启动,选择1安装系统,选择4则可以修改root ...

  3. php里面的socket编程,详解PHP Socket 编程过程

    详解PHP Socket 编程过程 作者:PHPYuan 时间:2019-03-13 03:41:20 概述 Socket用于进程间通信.进程间通信通常基于客户端-服务端模型.此时,客户端-服务端是可 ...

  4. XGBRegressor参数详解以及调参过程

    XGBRegressor参数详解以及调参过程 一.参数 1.通用参数booster.nthread 2.学习目标参数 (1)objective (2)eval_metric (3)seed 3.Tre ...

  5. Mac下使用Fiddler抓包详解(个人使用过程)

    Mac下使用Fiddler抓包详解(个人使用过程) 前言 1.VMware Fusion for Mac 2.win7镜像 3.windows版fiddler mac使用Windows fiddler ...

  6. “iOS 推送通知”详解:从创建到设置到运行

    "iOS 推送通知"详解:从创建到设置到运行 转自 http://www.csdn.net/article/2012-02-18/311976 这是一篇编译的文章,内容均出自Par ...

  7. CSS3新特性详解(二):CSS3 字体@font-face详解、如何创建和修改woff字体文件及text-shadow等文本效果

      关于CSS3新特性,在上篇博文中"CSS3新特性详解(一):CSS3选择器.边框.背景使用细节及案例演示",讨论了CSS3选择器.边框和背景,本文讨论字体@font-face使 ...

  8. Android Retrofit详解(retrofit:2.3.0)

    目录 1.Retrofit是什么? 2.Retrofit如何使用? 2.1创建HTTP请求的API接口 2.2请求执行 3.注解详情 3.1请求方法注解 3.2标记请求数据类型 3.3注解参数 4.G ...

  9. 红黑树操作详解——很形象的过程

    红黑树是一种很好的自平衡二叉排序树,在此,给出一个网友给出的红黑树操作详解: https://segmentfault.com/a/1190000012728513 里面给出了红黑树的详细操作,过程很 ...

最新文章

  1. linux apache2.4 php,php5.6+apache2.4+linux如何搭建php环境
  2. html5圆形图片轮播,jQuery超酷响应式圆形图片轮播图特效
  3. 原始Dao开发方法以及存在的问题
  4. linux swftools java_linux下安装swftools工具
  5. 6-Spring Boot缓存管理
  6. 用Python实现ax²+by的图灵机【形式语言与自动机】
  7. IIS(IISReset.exe)命令行(备忘)
  8. ITOP4412开发板学习前的准备2 -- 安装ADB驱动
  9. C++大纲显示:vs将if、for等语句块折叠
  10. JAVA中什么 和 什么的区别--面试最经常问的(全)
  11. 感谢生命中的每一次遇见
  12. Vivado IP核之复数浮点数乘法 Floating-point
  13. Windows管理用户账号
  14. aria2 32bit Android,【各版本整合】32/64位Aria2 Tools - 支持RPC协议 AriaNG(客户端+网页版)...
  15. [转] 大型ORACLE数据库优化设计方案
  16. c语言程序编写字体,c语言程序设计练习题
  17. 电力VR技术来进行安全教育培训有什么好处广州华锐互动
  18. vue 项目中引用并使用cdn上面的js文件
  19. 河北计算机一级考试试题,河北计算机一级试题及答案.doc
  20. 实验操作:Squid代理服务器应用(传统代理透明代理)--------------------------------------就整吧

热门文章

  1. 同一页面无法显示多个模态框的解决办法
  2. 归一化php,归一化函数normalize详解
  3. 2021全球与中国波长选择开关(WSS)市场现状及未来发展趋势
  4. SPI的NSS硬件模式
  5. iPhone 13 支持卫星上网?没那么简单
  6. 把Safari整个页面翻译成中文,,
  7. 风暴孵化:手游代理加盟水很深,如何避免入坑?
  8. 手游代理加盟最准解释来了
  9. 手游传奇代理一个版本大概多少
  10. 玩转ChatGPT:Auto-GPT项目部署与测评