深入剖析 Android 网络开源库 Retrofit 的源码详解

06-28 1513阅读

文章目录

  • 概述
  • 一、Retrofit 简介
    • Android主流网络请求库
    • 二、Retrofit 源码剖析
      • 1. Retrofit 网络请求过程
      • 2. Retrofit 实例构建
        • 2.1 Retrofit.java
        • 2.2 Retrofit.Builder()
          • 2.2.1 Platform.get()
          • 2.2.2 Android 平台
          • 2.3 Retrofit.Builder().baseUrl()
          • 2.4 Retrofit.Builder.client()
          • 2.5 Retrofit.Builder.addConverterFactory()
            • 2.5.1 GsonConverterFactory.create()
            • 2.6 Retrofit.Builder.addCallAdapterFactory()
              • 2.6.1 RxJava2CallAdapterFactory.create()
              • 2.7 Retrofit.Builder.build()
              • 3. Retrofit 创建网络请求接口实例
                • 3.1 Retrofit.create()
                • 3.2 Retrofit.loadServiceMethod()
                • 3.3 ServiceMethod.parseAnnotations()
                  • 3.3.1 RequestFactory.parseAnnotations()
                  • 3.4 HttpServiceMethod.parseAnnotations()
                    • 3.4.1 HttpServiceMethod.createCallAdapter()
                    • 3.4.2 Retrofit.callAdapter()
                    • 3.4.3 HttpServiceMethod.createResponseConverter()
                    • 3.4.4 Retrofit.responseBodyConverter()
                    • 3.4.5 GsonConverterFactory.responseBodyConverter()
                    • 3.4.6 GsonResponseBodyConverter
                    • 3.5 HttpServiceMethod
                    • 3.6 OkHttpCall
                    • 3.7 RxJava2CallAdapter.adapt()
                    • 小结
                    • 4. Retrofit 执行网络请求
                      • 4.1 Observable.subscribe()
                      • 4.2 BodyObservable.subscribeActual()
                      • 4.3 CallObservable.subscribeActual()
                      • 4.4 OkHttpCall.execute()
                        • 4.4.1 RequestFactory.create()
                        • 4.4.2 OkHttpClient.newCall()
                        • 4.4.3 RealCall.newRealCall()
                        • 4.5 OkHttpCall.parseResponse()
                          • 4.5.1 GsonResponseBodyConverter.convert()
                          • 4.5.2 Gson.getAdapter()
                          • 4.5.3 ReflectiveTypeAdapterFactory.Adapter.read()
                          • 4.6 Response.success()
                          • 小结
                          • 总结
                          • 参考

                            概述

                            在 Android 开发中,通过网络请求获取服务端数据是一项基本且常见的需求。目前有多种网络请求框架可供选择,其中 Android-Async-Http、Volley、OkHttp 和 Retrofit 是较为流行的、开源的网络请求框架。如何选择它们?孰优孰劣?仁者见仁智者见智,我个人觉得适合的就是最好的,不要盲目跟风去更换掉之前选用的网络请求框架,毕竟老代码那是牵一发而动全身哈!对于新项目来说,选择一个好用的网络请求框架,还是很有必要的,而 Retrofit 作为当下最火的一个网络开源请求库,还是值得学习并尝试使用的。


                            一、Retrofit 简介

                            Retrofit 是一个在 Android 开发中常用的网络请求框架。是 Square 公司基于他们自己的另一个比较火的网络库 OkHttp,进行封装的一个 RESTful 的 HTTP 网络请求框架。其提供了简洁而强大的 API,用于与 RESTful 服务进行通信。

                            • App 应用程序通过 Retrofit 请求网络,实际上是使用 Retrofit 接口层封装请求参数、Header、Url 等信息,之后由 OkHttp 完成后续的请求操作;
                            • 请求获取到服务端的响应后,OkHttp 将服务端返回的、原始的数据交给 Retrofit, Retrofit 再根据用户的需求对结果进行解析。

                              Retrofit 的一些主要特点和优势:

                              • 简单易用的 API:Retrofit 提供了简洁、直观的 API,使得定义和执行网络请求变得非常简单。通过定义接口,并使用注解来描述请求参数和响应数据,可以轻松地与 RESTful API 进行交互;
                              • 自动化网络请求处理:Retrofit 处理了大部分网络请求的细节,包括请求的构建、执行、响应的解析等,大大简化了网络请求的代码编写过程;
                              • 内置支持 RxJava:Retrofit 2.0 内置支持 RxJava,可以方便地将网络请求转换为 Observables 或 Singles,实现更加优雅的异步编程模式;
                              • 请求和响应的数据转换:Retrofit 支持多种数据格式的转换,包括:Gson、JSON、XML、Protobuf 等,可以方便地进行数据的序列化和反序列化;
                              • 灵活的请求配置:Retrofit 允许你配置全局的请求参数,包括:连接超时、读取超时、请求头、日志输出等,以满足不同场景下的需求;
                              • 强大的错误处理机制:Retrofit 提供了灵活的错误处理机制,可以根据不同的 HTTP 状态码和错误情况进行统一处理,使得应用程序在遇到错误时能够优雅地处理并给出相应的提示。

                                Retrofit 与其它主流网络请求库之间的功能与区别:

                                深入剖析 Android 网络开源库 Retrofit 的源码详解

                                二、Retrofit 源码剖析

                                1. Retrofit 网络请求过程

                                深入剖析 Android 网络开源库 Retrofit 的源码详解

                                结合上图,解释一下 Retrofit 网络请求过程:

                                1. 通过解析网络请求接口的注解配置网络请求参数
                                2. 通过动态代理生成网络请求对象
                                3. 通过网络请求适配器将网络请求对象进行平台适配(包括:Android、RxJava、Guava 和 Java8)
                                4. 通过网络请求执行器发送网络请求
                                5. 通过数据转换器解析服务器返回的数据
                                6. 通过回调执行器切换线程(子线程切到主线程)
                                7. 用户在主线程处理并展示返回结果

                                本文不准备详细介绍 Retrofit 的使用,主要是深入源码剖析其原理,下面就根据上面的请求过程,逐步剖析 Retrofit 的源码调用过程,注意:后续的源码基于 Retrofit 2.5.0 版本进行分析。

                                2. Retrofit 实例构建

                                Retrofit 实例是使用建造者模式通过 Builder 类进行创建的:

                                OkHttpClient client = new OkHttpClient.Builder()
                                		.addInterceptor(new TokenHeaderInterceptor()) // 动态添加token
                                		.addInterceptor(new NullResponseInterceptor()) // 返回空字符的时候显示
                                		.connectTimeout(CONNECTION_TIMEOUT, TimeUnit.SECONDS)
                                		.writeTimeout(CONNECTION_TIMEOUT, TimeUnit.SECONDS)
                                		.readTimeout(CONNECTION_TIMEOUT, TimeUnit.SECONDS)
                                		.build();
                                Retrofit retrofit = new Retrofit.Builder()
                                        .baseUrl(mBaseUrl)
                                        .client(client) // okhttp实例对象
                                        .addConverterFactory(GsonConverterFactory.create()) // 添加转换器工厂
                                        .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) // 请求指定适配器 RxJava
                                        .build();
                                

                                2.1 Retrofit.java

                                public final class Retrofit {
                                  // 网络请求配置对象(对网络请求接口中方法注解进行解析后得到的对象)
                                  // 作用:存储网络请求相关的配置,如网络请求的方法、数据转换器、网络请求适配器、网络请求工厂、基地址等
                                  private final Map responseBodyConverter(Type type, Annotation[] annotations,
                                      Retrofit retrofit) {
                                    TypeAdapter adapter = gson.getAdapter(TypeToken.get(type));
                                    return new GsonResponseBodyConverter(gson, adapter);
                                  }
                                  @Override
                                  public Converter adapter = gson.getAdapter(TypeToken.get(type));
                                    return new GsonRequestBodyConverter(gson, adapter);
                                  }
                                }
                                

                                GsonConverterFactory.creat() 方法中创建了一个含有 Gson 实例的 GsonConverterFactory 实例对象, 并返回给 Builder.addConverterFactory() 方法作为方法的入参将其放入到 converterFactories 集合中。

                                2.6 Retrofit.Builder.addCallAdapterFactory()

                                public final class Retrofit {
                                  public static final class Builder {
                                	......
                                	private final List callAdapterFactories = new ArrayList();
                                	......
                                    // 添加网络请求 Call 的适配器工厂,以支持除 Call 以外的服务方法返回类型
                                    public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
                                      callAdapterFactories.add(checkNotNull(factory, "factory == null"));
                                      return this;
                                    }
                                  }
                                }
                                

                                Builder.addCallAdapterFactory() 方法为网络请求 Call 添加适配器工厂,以支持除 Call 以外的服务方法返回类型。本文以 RxJava2CallAdapterFactory 为例,调用 RxJava2CallAdapterFactory.create() 方法来创建实例对象。

                                2.6.1 RxJava2CallAdapterFactory.create()
                                public final class RxJava2CallAdapterFactory extends CallAdapter.Factory {
                                  public static RxJava2CallAdapterFactory create() {
                                    // 继续调用 RxJava2CallAdapterFactory 有参构造方法,只是 Scheduler 传入为 null
                                    return new RxJava2CallAdapterFactory(null);
                                  }
                                  
                                  private final Scheduler scheduler;
                                  private RxJava2CallAdapterFactory(Scheduler scheduler) {
                                    this.scheduler = scheduler;
                                  }
                                  
                                  @Override
                                  public CallAdapter get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
                                    Class rawType = getRawType(returnType); // 获取当前方法参数的具体类型
                                    if (rawType == Completable.class) { // 返回类型是否是Completable类
                                      // Completable 没有参数化(这是该方法的其余部分所处理的),因此只能用单个配置创建它
                                      return new RxJava2CallAdapter(Void.class, scheduler, false, true, false, false, false, true);
                                    }
                                	// 由于本文是结合 RxJava 进行使用的,因此返回值类型是 Observable 类型的
                                    boolean isFlowable = rawType == Flowable.class; // isFlowable 为 false
                                    boolean isSingle = rawType == Single.class; 	// isSingle 为 false
                                    boolean isMaybe = rawType == Maybe.class; 		// isMaybe 为 false
                                    if (rawType != Observable.class && !isFlowable && !isSingle && !isMaybe) {
                                      return null; // 不是 Completable、Flowable、Single、Maybe 和 Observable 则返回 null
                                    }
                                    boolean isResult = false;
                                    boolean isBody = false;
                                    Type responseType;
                                    if (!(returnType instanceof ParameterizedType)) { // 非参数化类型
                                      String name = isFlowable ? "Flowable" : isSingle ? "Single" : "Observable";
                                      throw new IllegalStateException(name + " return type must be parameterized"
                                          + " as " + name + " or " + name + "
VPS购买请点击我

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

目录[+]