retrofit源码分析

概述

image.png

retrofit是okhttp网络框架的封装。

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

动态代理了解

https://www.jianshu.com/p/f4208b50f638

通信八步

  1. 创建retrofit 实例
  2. 定义一个网络请求接口,并为接口中的方法添加注解(get post等)
  3. 通过 动态代理生成网络 请求对象。 其实就是解析网络请求接口中的注解,解析完之后来配置我们的网络请求参数。最终通过动态代理拦截生成网络请求对象的。
  4. 通过 网络请求适配器,将网络请求对象进行平台适配。
  5. 通过 网络请求执行器call 发送网络请求
  6. 通过 数据转化器 解析数据
  7. 通过 回调执行器 切换线程
  8. 用户在主线程处理返回结果

实现

    public static RetrofitService getRetrofit() {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(Api.APP_DOMAIN)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .build();
        retrofitService = retrofit.create(RetrofitService.class);
        return retrofitService;
    }

Retrofit 源码---七个成员变量的解释

public final class Retrofit {
<-------七个成员变量的解释------>
//key值:Method: http请求的方法
//value值:ServiceMethod:注解(网络请求接口中方法的注解)解析之后的对象就是ServiceMethod
//serviceMethodCache:作用:存储网络请求相关的配置,如网络请求的方法、数据转换器、网络请求适配器、网络请求工厂、基地址等
  private final Map<Method, ServiceMethod<?, ?>> serviceMethodCache = new ConcurrentHashMap<>();

  // 网络请求器的工厂
  // 作用:生产网络请求器OkHttpClient
  // Retrofit是默认使用okhttp
  final okhttp3.Call.Factory callFactory;

 //网络请求url的基地址
  final HttpUrl baseUrl;

//数据转化器工厂集合:放置数据转换器的工厂
//工厂的作用是生成我们//数据转化器(converter)
//数据转化器作用:他对我们请求网络回来的结果response进行转换,把它转换成我们能用的java对象
  final List<Converter.Factory> converterFactories;

  // 网络请求适配器工厂的集合, 作用:放置网络请求适配器工厂
  // 网络请求适配器工厂作用:生产网络请求适配器(CallAdapter)
  // CallAdapter适配器作用:把call对象转换成其他类型,比如如果平台想支持rxjava的话,这个时候,可以把call转化成rxjava的call
  final List<CallAdapter.Factory> callAdapterFactories;

//工厂模式:将类实例化的操作与使用对象的操作分开,这样客户端在使用的时候,不需要知道具体的参数,直接通过Factory提供给我们的静态方法就可以创建想要的对象

//用于执行回调,安卓中默认主线程的MainThreadExecutor
  final @Nullable Executor callbackExecutor;

// 标志位
// 作用:是否提前对业务接口中的注解进行验证转换的标志位
  final boolean validateEagerly;
}

Retrofit 源码---Retrofit类中的Builder类

使用Builder的时候,对Retrofit初始化

public static final class Builder {
    //适配平台:比如android、ios、java8等,默认是android
    private final Platform platform;
    //以下同Retrofit类里面的成员变量的含义
    private @Nullable okhttp3.Call.Factory callFactory;
    private HttpUrl baseUrl;
    private final List<Converter.Factory> converterFactories = new ArrayList<>();
    private final List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>();
    private @Nullable Executor callbackExecutor;
    private boolean validateEagerly;

//Builder方法,下面我们看一下Platform.get()
 public Builder() {
      this(Platform.get());
    }
}
...

看一下Platform这个类

class Platform {
  private static final Platform PLATFORM = findPlatform();

<---------1. get()方法,返回的是findPlatform(),看一下findPlatform()------------->
  static Platform get() {
    return PLATFORM;
  }

<---------2. 看一下findPlatform()------------->
  private static Platform findPlatform() {
    try {
    //通过这个类确定是android平台,下面看一下Android();
      Class.forName("android.os.Build");
      if (Build.VERSION.SDK_INT != 0) {
        return new Android();
      }
    } catch (ClassNotFoundException ignored) {
    }
    try {
  //通过这个类确定是java8平台。
      Class.forName("java.util.Optional");
      return new Java8();
    } catch (ClassNotFoundException ignored) {
    }
    return new Platform();
  }

  @Nullable Executor defaultCallbackExecutor() {
    return null;
  }

  CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
    if (callbackExecutor != null) {
      return new ExecutorCallAdapterFactory(callbackExecutor);
    }
    return DefaultCallAdapterFactory.INSTANCE;
  }

  boolean isDefaultMethod(Method method) {
    return false;
  }

  @Nullable Object invokeDefaultMethod(Method method, Class<?> declaringClass, Object object,
      @Nullable Object... args) throws Throwable {
    throw new UnsupportedOperationException();
  }

  @IgnoreJRERequirement // Only classloaded and used on Java 8.
  static class Java8 extends Platform {
    @Override boolean isDefaultMethod(Method method) {
      return method.isDefault();
    }

    @Override Object invokeDefaultMethod(Method method, Class<?> declaringClass, Object object,
        @Nullable Object... args) throws Throwable {
      // Because the service interface might not be public, we need to use a MethodHandle lookup
      // that ignores the visibility of the declaringClass.
      Constructor<Lookup> constructor = Lookup.class.getDeclaredConstructor(Class.class, int.class);
      constructor.setAccessible(true);
      return constructor.newInstance(declaringClass, -1 /* trusted */)
          .unreflectSpecial(method, declaringClass)
          .bindTo(object)
          .invokeWithArguments(args);
    }
  }

<------------3.Android这个类---------------------------->
// 线程切换是通过一开始创建Retrofit对象时,调用Builder()时,Platform在检测到运行环境是Android时进行创建的
// 采用适配器模式
  static class Android extends Platform {
    @Override public Executor defaultCallbackExecutor() {
     // 返回一个默认的回调方法执行器
      // 该执行器作用:切换线程(子->>主线程),并在主线程(UI线程)中执行回调方法
MainThreadExecutor()
      return new MainThreadExecutor();
    }

    // 创建默认的网络请求适配器工厂
    // 该默认工厂生产的 adapter 会使得Call在异步调用时在指定的 Executor 上执行回调
    // 在Retrofit中提供了四种CallAdapterFactory: ExecutorCallAdapterFactory(默认)、GuavaCallAdapterFactory、Java8CallAdapterFactory、RxJavaCallAdapterFactory
    // 采用了策略模式
    @Override CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
      if (callbackExecutor == null) throw new AssertionError();
      return new ExecutorCallAdapterFactory(callbackExecutor);
    }

<------------4.MainThreadExecutor---------------------------->
    static class MainThreadExecutor implements Executor {
//绑定到主线程的Handler
      private final Handler handler = new Handler(Looper.getMainLooper());

      @Override public void execute(Runnable r) {
       // 该Handler是上面获取的与Android 主线程绑定的Handler 
        // 在UI线程进行对网络请求返回数据处理等操作。
        handler.post(r);
      }
    }
  }
}
//// 切换线程的流程:
// 1. 回调ExecutorCallAdapterFactory生成了一个ExecutorCallbackCall对象
//2. 通过调用ExecutorCallbackCall.enqueue(CallBack)从而调用MainThreadExecutor的execute()通过handler切换到主线程

.baseUrl(Api.APP_DOMAIN)方法

把baseurl转化成适合okhttp请求的url变量,具体如下

  public Builder baseUrl(String baseUrl) {
      //判空
      checkNotNull(baseUrl, "baseUrl == null");
      //string类型转换成HttpUrl类型
      HttpUrl httpUrl = HttpUrl.parse(baseUrl);
      if (httpUrl == null) {
        throw new IllegalArgumentException("Illegal URL: " + baseUrl);
      }
<-------看下一个类------->
      return baseUrl(httpUrl);
    }

上面baseUrl类

    public Builder baseUrl(HttpUrl baseUrl) {
      checkNotNull(baseUrl, "baseUrl == null");
   //依次提取出Path的各个部分的字符串
      List<String> pathSegments = baseUrl.pathSegments();
//如果baseurl不是以"/"的结尾,就会抛出异常
      if (!"".equals(pathSegments.get(pathSegments.size() - 1))) {
        throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl);
      }
      this.baseUrl = baseUrl;
      return this;
    }

.addConverterFactory(GsonConverterFactory.create())方法

    /** Add converter factory for serialization and deserialization of objects. */
    public Builder addConverterFactory(Converter.Factory factory) {
   //converterFactories对象是retrofit成员变量,上面有讲
    //add添加了一个我们创建的factory:GsonConverterFactory
      converterFactories.add(checkNotNull(factory, "factory == null"));
      return this;
    }

下面看一下GsonConverterFactory.create()方法

  public static GsonConverterFactory create() {
  //看一下以下的creat(Gson gson)方法
    return create(new Gson());
  }
  public static GsonConverterFactory create(Gson gson) {
    if (gson == null) throw new NullPointerException("gson == null");
  //接下来看GsonConverterFactory(Gson gson)
    return new GsonConverterFactory(gson);
  }
  private final Gson gson;
  private GsonConverterFactory(Gson gson) {
    this.gson = gson;
  }

实际上:GsonConverterFactory.create()创建来一个带Gson gson的实例的GsonConverterFactory对象,然后返回给addConverterFactory()方法。

.addCallAdapterFactory(RxJavaCallAdapterFactory.create())

 public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
//callAdapterFactories是retrofit的成员变量,上面说过。
//作用是将factory:RxJavaCallAdapterFactory.create()添加到callAdapterFactories集合中
      callAdapterFactories.add(checkNotNull(factory, "factory == null"));
      return this;
    }

接下来看一下RxJavaCallAdapterFactory.create()

  public static RxJavaCallAdapterFactory create() {
    return new RxJavaCallAdapterFactory(null, false);
  }

  private RxJavaCallAdapterFactory(@Nullable Scheduler scheduler, boolean isAsync) {
    this.scheduler = scheduler;
    this.isAsync = isAsync;
  }

实际上:RxJavaCallAdapterFactory.create()创建来一个带Scheduler scheduler、boolean isAsync的实例的RxJavaCallAdapterFactory对象,然后返回给addCallAdapterFactory()方法。

.build()方法

   public Retrofit build() {
 //baseurl非空判断
      if (baseUrl == null) {
        throw new IllegalStateException("Base URL required.");
      }

      okhttp3.Call.Factory callFactory = this.callFactory;
   //retrofit默认okhttp进行网络请求
      if (callFactory == null) {
        callFactory = new OkHttpClient();
      }

// callbackExecutor 用于线程切换
      Executor callbackExecutor = this.callbackExecutor;
      if (callbackExecutor == null) {
//默认创建的是主线程的Executor
        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工厂集合添加默认的调用适配器工厂
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.
  //通过传入BuiltInConverters()对象配置数据转换器工厂(converterFactories)
// converterFactories是一个存放数据转换器Converter.Factory的数组
// 配置converterFactories即配置里面的数据转换器
// BuiltInConverters是一个内置的数据转换器工厂(继承Converter.Factory类)new BuiltInConverters():是为了初始化数据转换器
      converterFactories.add(new BuiltInConverters());
      converterFactories.addAll(this.converterFactories);

    //创建Retrofit对象
      return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
          unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
    }
  }

build()方法就是把Retrofit类里面的成员变量都配置完毕。

RxJavaCallAdapterFactory分析

RxJavaCallAdapterFactory是继承 abstract class Factory类的,Factory是定义在CallAdapter接口中的

CallAdapter
image.png

作用:CallAdapter将retrofit的call对象转化成java对象,retrofit中的call和okhttp的call不太一样,retrofit的call对okhttp中的call进行了封装。
具体过程:


image.png

关于coverter,他可以根据addConverterFactory进行个性化配置,如果不配置retrofit默认配置GsonConverterFactory

CallAdapter类源码
public interface CallAdapter<R, T> {
//我们所需要的接口数据解析后的类型
  Type responseType();

//T类型是我们需要转换成接口的返回类型,Call:是okhttp的call
  T adapt(Call<R> call);

//当我们addCallAdapterFactory里面的工厂类的时候,里面工程类需要继承Factory这个类。
abstract class Factory {

//根据接口返回类型、注解类型,得到实际需要的callAdapter
    public abstract @Nullable CallAdapter<?, ?> get(Type returnType, Annotation[] annotations,
        Retrofit retrofit);
  protected static Type getParameterUpperBound(int index, ParameterizedType type) {
      return Utils.getParameterUpperBound(index, type);
    }

//获取接口数据原始类型
    protected static Class<?> getRawType(Type type) {
      return Utils.getRawType(type);
    }
  }
}
rxjava如何运作

RxJavaCallAdapterFactory:


image.png

RxJavaCallAdapterFactory实现Factory抽象类,用来提供具体的适配逻辑,然后通过addCallAdapterFactory(allAdapter.Factory factory)方法注册CallAdapte,然后调用Factory里面回调回来的get(Type returnType, Annotation[] annotations,Retrofit retrofit)方法获取CallAdapter对象,最后调用CallAdapter的adapt(Call<R> call)方法,这个方法把call请求转化成每一个平台所试用的类型

get方法

@Override
  public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
//获取原始数据类型
    Class<?> rawType = getRawType(returnType);
//下面判断rawType是否是rxjava类型的
    boolean isSingle = rawType == Single.class;
    boolean isCompletable = rawType == Completable.class;
    if (rawType != Observable.class && !isSingle && !isCompletable) {
      return null;
    }

    if (isCompletable) {
      return new RxJavaCallAdapter(Void.class, scheduler, isAsync, false, true, false, true);
    }

    boolean isResult = false;
    boolean isBody = false;
    Type responseType;
    if (!(returnType instanceof ParameterizedType)) {
      String name = isSingle ? "Single" : "Observable";
      throw new IllegalStateException(name + " return type must be parameterized"
          + " as " + name + "<Foo> or " + name + "<? extends Foo>");
    }

    Type observableType = getParameterUpperBound(0, (ParameterizedType) returnType);
    Class<?> rawObservableType = getRawType(observableType);
    if (rawObservableType == Response.class) {
      if (!(observableType instanceof ParameterizedType)) {
        throw new IllegalStateException("Response must be parameterized"
            + " as Response<Foo> or Response<? extends Foo>");
      }
      responseType = getParameterUpperBound(0, (ParameterizedType) observableType);
    } else if (rawObservableType == Result.class) {
      if (!(observableType instanceof ParameterizedType)) {
        throw new IllegalStateException("Result must be parameterized"
            + " as Result<Foo> or Result<? extends Foo>");
      }
      responseType = getParameterUpperBound(0, (ParameterizedType) observableType);
      isResult = true;
    } else {
      responseType = observableType;
      isBody = true;
    }

//最后会返回一个RxJavaCallAdapter的实现对象
    return new RxJavaCallAdapter(responseType, scheduler, isAsync, isResult, isBody, isSingle,
        false);
  }
}

接下来就会调RxJavaCallAdapter里面的adapt()方法

RxJavaCallAdapter类

final class RxJavaCallAdapter<R> implements CallAdapter<R, Object> {
  private final Type responseType;
  private final @Nullable Scheduler scheduler;
  private final boolean isAsync;
  private final boolean isResult;
  private final boolean isBody;
  private final boolean isSingle;
  private final boolean isCompletable;

  RxJavaCallAdapter(Type responseType, @Nullable Scheduler scheduler, boolean isAsync,
      boolean isResult, boolean isBody, boolean isSingle, boolean isCompletable) {
    this.responseType = responseType;
    this.scheduler = scheduler;
    this.isAsync = isAsync;
    this.isResult = isResult;
    this.isBody = isBody;
    this.isSingle = isSingle;
    this.isCompletable = isCompletable;
  }

  @Override public Type responseType() {
    return responseType;
  }

  @Override public Object adapt(Call<R> call) {
//被观察者,创建他的实例,将call对象和被观察进行关联
    OnSubscribe<Response<R>> callFunc = isAsync
        ? new CallEnqueueOnSubscribe<>(call)
        : new CallExecuteOnSubscribe<>(call);

    OnSubscribe<?> func;
    if (isResult) {
      func = new ResultOnSubscribe<>(callFunc);
    } else if (isBody) {
      func = new BodyOnSubscribe<>(callFunc);
    } else {
      func = callFunc;
    }
    Observable<?> observable = Observable.create(func);

    if (scheduler != null) {
//执行retrofit中的网络请求
      observable = observable.subscribeOn(scheduler);
    }

    if (isSingle) {
      return observable.toSingle();
    }
    if (isCompletable) {
      return observable.toCompletable();
    }
    return observable;
  }
}

addCallAdapterFactory总结


image.png

获取call对象,执行http请求,retrofit调用call请求,其实最终调用的是okhttp当中的call,只不过retrofit对call进行类封装,然后就可以获取到服务端返回对数据,获取到数据以后调用converter把所需要的对象转化出java对象来。
每个需要不同的适配器工厂,所以addCallAdapterFactory实现:
实现CallAdapter.Factory抽象类,然后注册到CallAdapter中,通过Factory的get方法获取CallAdapter对象,CallAdapter对象调用adapter方法,将call请求转化成每个平台所试用的对象类型。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345