Retrofit 源码分析

栏目: Android · 发布时间: 5年前

内容简介:至此,一个简单的使用retrofit网络请求完成。推荐阅读知其然知其所以然,一起看看原理是怎么实现的。
  • 第一步:定义网络请求接口类
public interface MyApi {
    @FormUrlEncoded
    @POST
    Call<ResponseBody> getData(@Field("userId") String userId);
}
复制代码
  • 第二步:初始化retrofit实例
Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("这里放基础url")
                .build();
复制代码
  • 第三步:生成接口实现类
MyApi api = retrofit.create(MyApi.class);
复制代码
  • 第四步:调用接口方法,发起请求
Call<ResponseBody> call = api.getData("1234");
//post请求
call.enqueue(new Callback<ResponseBody>() {
    @Override
    public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {

    }

    @Override
    public void onFailure(Call<ResponseBody> call, Throwable t) {

    }
});
//get请求
call.request();
复制代码

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

推荐阅读 这是一份很详细的 Retrofit 2.0 使用教程(含实例讲解)

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<String> 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<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
      callAdapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));

      // Make a defensive copy of the converters.
      List<Converter.Factory> 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原理解析最简洁的思路

参考流程图

Retrofit 源码分析

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Nginx高性能Web服务器详解

Nginx高性能Web服务器详解

苗泽 / 电子工业出版社 / 2013-10 / 59.00元

《Nginx高性能Web服务器详解》全面介绍了当前Internet上流行的一款开放源代码的Web服务器——Nginx。全书一共分为四大部分,分别从入门、功能、实现和应用等四个方面对Nginx服务器的知识进行完整阐述,从而满足广大读者在应用Nginx服务器时的普遍性需求。同时也深入剖析了Nginx服务器的工作原理和实现技术,对其中使用到的数据结构和方法进行了详细阐述,并且结合实际的应用情况给出了多个......一起来看看 《Nginx高性能Web服务器详解》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

MD5 加密
MD5 加密

MD5 加密工具