源码分析;Retrofit处理HTTP请求主要流程

1. 写在前面

程序员界的2-8定律:80%的问题只需要使用20%的知识就可以解决,Android开发也不例外。因而,我们大部分人已经逐步变成了代码搬运工而自己却不知道。代码容易搬运,架构体系却难以复制,要成为架构师,你必须自己亲自去项目实战,读源码,研究原理。

Retrofit和OkHttp都来自于Square公司,而且都是在用来处理HTTP请求的,先来看下用OkHttp处理HTTP请求的实现:

 

String url = "https://api.github.com/users/octocat/repos";
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
        .url(url)
        .build();
client.newCall(request).enqueue(new okhttp3.Callback() {
    @Override
    public void onFailure(okhttp3.Call call, IOException e) {

    }

    @Override
    public void onResponse(okhttp3.Call call, Response response) throws IOException {
        List<Repo> repos = JSON.parseArray(response.body().toString(), Repo.class);
    }
});

可以看到在发起HTTP请求之前需要构造Request对象,请求完成后还需要将Response转化成所需要的对象,如果每一个HTTP请求都要这么复杂,那对于需要成百上千个HTTP请求的应用来说无疑是多了很多的重复代码,对于一个追求完美的程序员来说是无法容忍的;因此Square公司推出了Retrofit框架,Retrofit的中文意思是改造,顾名思义就是在OkHttp的基础上的进行的一次升级和封装,Retrofit通过定义接口的方式来构建Request对象,通过Converter将Response转化为需要的对象,这就是Retrofit存在的意义,下面看一下通过Retrofit框架实现与上面一样的功能:

 

// 构建Retrofit实例,一般都是通过单例模式创建的,所以一般会创建一个Manager类来创建和管理Retrofit对象
Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("https://api.github.com/")
        // 添加一个用来创建Converter实例的工厂,该工厂是针对于json字符串的
        .addConverterFactory(FastJsonConverterFactory.create())
        .build();

// 在一个项目中,都是会对HTTP请求进行分类的,每一个分类都会创建一个与之对应的一个接口(比如下面的GitHubService接口)
// 每一个接口包含多个方法,每一个方法对应于一个HTTP请求(执行的时候会根据方法来构建Request对象)
// 每一个方法的返回值都是一个Call对象,默认是ExecutorCallbackCall对象,针对于rxjava2就是返回的就是Observable对象
public interface GitHubService {
    @GET("users/{user}/repos")
    Call<List<Repo>> listRepos(@Path("user") String user);
}

// 下面就是发起HTTP的代码,相比于OkHttp来说简化了Request对象的构建和Response的解析
GitHubService service = retrofit.create(GitHubService.class);
Call<List<Repo>> repos = service.listRepos("octocat");
repos.enqueue(new Callback<List<Repo>>() {
    @Override
    public void onResponse(Call<List<Repo>> call, retrofit2.Response<List<Repo>> response) {
        List<Repo> repoList = response.body();
    }

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

    }
});

上面代码中提到的Call对象,其实是对OkHttp中RealCall的封装,这样的设计也体现了一种设计模式(门面模式):

 

门面模式(Facade Pattern)也叫做外观模式,是一种比较常用的封装模式,其定义如下:
Provide a unified interface to a set of interfaces in a subsystem.
Facade defines a higher-level interface that makes the subsystem easier to use.
(要求一个子系统的外部和内部的通信必须通过一个统一的对象进行。门面模式提供一个高层次的接口,
使得子系统更易于使用。)

所以Retrofit示例代码中提到的Call对象就是门面模式中说到的统一的对象。
Retrofit源码地址

2. 预备知识

2.1 Java编程语言中的Type

在Retrofit中会对Method实例(对应上面的例子,就是GitHubService的listRepos方法对应的实例)进行解析,因此会对Method实例的返回值类型和参数类型进行解析,所以这里带大家了解一下Java编程语言中的Type:

 

 

Type是Java 编程语言中所有类型的公共高级接口,Java 编程语言中的类型包括(其中后面四种类型是泛型的三种表现形式):
1 基本类型:也就是我们所说的java中的8中基本类型。
2 原始类型(raw types):对应Class。
3 类型变量(TypeVariable):
  该接口代表各种类型变量的公共接口,如Collection<T>中的T就是一个类型变量。
  主要方法:
  Type[] getBounds():获取上边界Type数组。
4 参数化类型(ParameterizedType):
  该接口代表参数化类型,例如Collection<String>。
  主要方法:
  Type[] getActualTypeArguments():获取参数化类型中的所有类型的数组。
  Type getRawType():获取参数化类型中<>前面的类型。
5 泛型数组类型(GenericArrayType):
  该接口代表一种数组类型,其组件类型为参数化类型或类型变量
  ,例如参数化类型数组Map<String, String>[]map和类型变量数组T[] arr。
  主要方法:
  Type getGenericComponentType():返回其组件类型。

除了上面泛型的三种表现形式外还有一种并不属于Java类型的表达形式:
通配符类型(WildcardType):
该接口代表通配符类型表达式,例如 如 ?、? extends Number 或 ? super Integer.
主要方法:
Type[] getUpperBounds():获取上边界Type数组。
Type[] getLowerBounds():获取下边界Type数组。

3. 源码分析

我会根据上面的例子解析分析,因此在分析的过程中会依赖上面的代码
首先看一下Retrofit处理http请求的时序图:

3.1 构建Retrofit实例

上图中的前8步通过建造者模式构建了一个Retrofit实例

 

建造者模式(Builder Pattern,也叫生成器模式)的定义:
Separate the construction of a complex object from its representation so that 
the same construction process can create different representations.
(将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。)

构建的过程也是对Retrofit实例进行初始化的过程,初始化的结果:
1> callFactory : 顾名思义是用来创建Call对象的,默认为OkHttpClient类型对象,没错,这就就是OkHttp中的OkHttpClient,通常情况下不会修改该默认值。
2> baseUrl</

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值