retrofit网络框架源码解析(二)

18 篇文章 0 订阅
  • App应用程序通过Retrofit 请求网络,实际上是使用Retrofit接口层封装请求参数,之后由OkHttp完成后续的请求操作。
  • 在服务器返回数据之后,OkHttp将原始的结果交给Retrofit,Retrofit根据用户的需求对结果进行解析。

一、retrofit框架网络请求过程7个步骤:

    1. 添加Retrofit库的依赖,添加网络权限
    1. 创建接收服务器返回数据的类
    1. 创建用于描述网络请求的接口
    1. 创建Retrofit实例
    1. 创建网络请求接口实例
    1. 发送网络请求(同步/异步)
    1. 处理服务器返回的数据

或者也可以将网络通信归纳成如下八步:

  1. 创建retrofit实例
  2. 定义一个网络请求接口并为接口中的方法添加注解
  3. 通过动态代理生产网络请求对象
  4. 通过网络请求适配器将网络请求对象进行平台适配
  5. 通过网络请求适配器发送网络请求
  6. 通过数据转换器解析数据
  7. 通过回调执行器切换线程
  8. 用户在主线程处理返回结果

二、代理

  • 静态代理模式:为其他对象提供一种代理,用以控制对这个对象的访问
    在这里插入图片描述

  • 动态代理模式:代理类在程序运行时创建的代理方式
    相比静态代理,动态代理的优势它能很方便的对我们代理类的函数进行统一的处理,不用频繁的修改每一个代理类函数
    (1)jdk动态代理–需要客户端辅助写些接口来操作
    (2)CGLIB–可以直接修改字节码

  • 每个代理类的对象都会关联一个表示内部处理逻辑的InvocationHandler接口的实现

  • invoke方法的参数中可以获取参数

  • invoke方法的返回值被返回给使用者

三、Retrofit源码解析

Retrofit中成员变量:

  1. private final Map<Method, ServiceMethod<?>> serviceMethodCache = new ConcurrentHashMap<>(); //key是Method为http请求的方法,value是ServiceMethod代表网络请求接口中对方法进行注解之后,通过进行解析之后的对象,跟注解中get、put等是成对出现、一一对应的。serviceMethodCache主要用于缓存,存储一些网络请求的相关配置和网络请求的方法、数据转换器、网络请求适配器等等。

  2. final okhttp3.Call.Factory callFactory; //请求网络的OkHttp的工厂,默认为OkHttpClient,该工厂的作用就是生产OkHttpClient

  3. final HttpUrl baseUrl; //网络请求的基地址,跟接口注解中的相对地址可以拼接成一个完整的请求地址

  4. final List<Converter.Factory> converterFactories; //数据转换器工厂的集合,数据转换器就是对请求网络之后得到的Response所进行的转换,转换成应用java对象,默认情况下使用的是GsonCoverterFactory。该集合就是用于放置数据转换器的工厂,同时这个工厂的作用也是用于生产所需要的数据转换器

  5. final List<CallAdapter.Factory> callAdapterFactories; //网络请求适配器的工厂集合,适配器就是把call对象转换成其他类型,比如Rxjava平台的call。该集合就是用于放置网络适配器工厂,同时这个工厂的作用也是用于生产CallAdapter

  6. final @Nullable Executor callbackExecutor; //用于执行回调,在Android平台中,默认使用的是MainThreadExecutor,即主线程中的executor

  7. final boolean validateEagerly; // 表示的是一个标志位,是否需要立即解析接口中的方法,该标志位是用于动态代理中解析定义好接口中的方法和注解当中

Retrofit内部类Builder的成员变量:

  1. private final Platform platform; //Retrofit适配的平台,包括android、ios、java8,默认情况下使用的是android平台

  2. private @Nullable okhttp3.Call.Factory callFactory; //表示请求网络的okhttp工厂,默认情况下使用的是okhttp来进行网络请求的,默认值为OkHttpClient

  3. private @Nullable HttpUrl baseUrl; //网络请求的Url基地址

  4. private final List<Converter.Factory> converterFactories = new ArrayList<>(); //数据转换器工厂的集合,数据转换器就是对请求网络之后得到的Response所进行的转换,转换成应用java对象,默认情况下使用的是GsonCoverterFactory。该集合就是用于放置数据转换器的工厂,同时这个工厂的作用也是用于生产所需要的数据转换器

  5. private final List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(); //网络请求适配器的工厂集合,适配器就是把call对象转换成其他类型,比如Rxjava平台的call。该集合就是用于放置网络适配器工厂,同时这个工厂的作用也是用于生产CallAdapter

  6. private @Nullable Executor callbackExecutor; //用于执行回调,在Android平台中,默认使用的是MainThreadExecutor,即主线程中的executor

  7. private boolean validateEagerly; /// 表示的是一个标志位,是否需要立即解析接口中的方法,该标志位是用于动态代理中解析定义好接口中的方法和注解当中
    Builder类中的2~7成员变量跟Retrofit类中的2-7成员变量是一样的

Retrofit的build()
作用:build()方法就是将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();  //默认使用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.addAll(platform.defaultCallAdapterFactories(callbackExecutor));

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

      // 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);
      converterFactories.addAll(platform.defaultConverterFactories());

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

CallAdapter
在这里插入图片描述

RxJavaCallAdapterFactory
在这里插入图片描述

retrofit请求

  • 同步:OkHttpCall.execute()
    在这里插入图片描述

  • 异步:OkHttpCall.enqueue()

Retrofit采用的设计模式:

    1. 构建者模式
Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://***.***.com/")  //设置网络请求的url地址,这个是基地址
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())  
                .addConverterFactory(AppGsonConverterFactory.create())  
                .build();
    1. 工厂模式

CallAdapter.Factory


  /**
   * Creates {@link CallAdapter} instances based on the return type of {@linkplain
   * Retrofit#create(Class) the service interface} methods.
   */
  abstract class Factory {
    /**
     * Returns a call adapter for interface methods that return {@code returnType}, or null if it
     * cannot be handled by this factory.
     */
    public abstract @Nullable CallAdapter<?, ?> get(
        Type returnType, Annotation[] annotations, Retrofit retrofit);

    /**
     * Extract the upper bound of the generic parameter at {@code index} from {@code type}. For
     * example, index 1 of {@code Map<String, ? extends Runnable>} returns {@code Runnable}.
     */
    protected static Type getParameterUpperBound(int index, ParameterizedType type) {
      return Utils.getParameterUpperBound(index, type);
    }

    /**
     * Extract the raw class type from {@code type}. For example, the type representing {@code
     * List<? extends Runnable>} returns {@code List.class}.
     */
    protected static Class<?> getRawType(Type type) {
      return Utils.getRawType(type);
    }
  }

RxJava2CallAdapterFactory和DefaultCallAdapterFactory 继承于CallAdapter.Factory类,并复写get()方法来返回不同的CallAdapter类型

    1. 静态工厂模式
public class Platform {
  private static final Platform PLATFORM = findPlatform();
  ... ...
  public static Platform get() {
    return PLATFORM;
  }
... ...

  /** Attempt to match the host runtime to a capable Platform implementation. */
  private static Platform findPlatform() {
    if (isAndroid()) {
      return findAndroidPlatform();
    } else {
      return findJvmPlatform();
    }
  }
  ... ...
    1. 外观/门面设计模式
      定义:外部与一个子系统进行通信,必须通过一个统一外观的对象(也就是门面)来进行。为这个子系统的一组接口提供一个一致的界面。对外提供统一的接口,方便与外部之间的通信
      在这里插入图片描述
Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://***.***.com/")  //设置网络请求的url地址,这个是基地址
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())  
                .addConverterFactory(AppGsonConverterFactory.create())  
                .build();

Retrofit类的设计就是一个外观模式

    1. 策略模式
      在这里插入图片描述
      Retrofit中的CallAdapter采用了策略模式

    策略模式和工厂模式的区别:策略模式强调的是不同对象的策略方法的具体实现,侧重于方法的实现;工厂模式强调的是生产对象

    1. 适配器模式
Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://***.***.com/")  //设置网络请求的url地址,这个是基地址
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())  //这个地方采用适配器模式  
                .addConverterFactory(AppGsonConverterFactory.create())   
                .build();

CallAdapter类中adapter()方法

  T adapt(Call<R> call);
    1. 动态代理模式
  public <T> T create(final Class<T> service) {
    validateServiceInterface(service);
    return (T)
        Proxy.newProxyInstance(
            service.getClassLoader(),
            new Class<?>[] {service},
            new InvocationHandler() {
              private final Platform platform = Platform.get();
              private final Object[] emptyArgs = new Object[0];

              @Override
              public @Nullable Object invoke(Object proxy, Method method, @Nullable Object[] args)
                  throws Throwable {
                // If the method is a method from Object then defer to normal invocation.
                if (method.getDeclaringClass() == Object.class) {
                  return method.invoke(this, args);
                }
                args = args != null ? args : emptyArgs;
                return platform.isDefaultMethod(method)
                    ? platform.invokeDefaultMethod(method, service, proxy, args)
                    : loadServiceMethod(method).invoke(args);
              }
            });
  }
    1. 观察者设计模式
      Call/OkHttpCall --> 被观察者
      异步请求的Callback -->观察者
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值