likes
comments
collection
share

Retrofit源码阅读

作者站长头像
站长
· 阅读数 15

1. Retrofit的简介与使用

1.1 Retrofit的简介

Retrofit主要是对OkHttp做了一层封装,利用注解的方式使得接口请求更简单,灵活的使用Converter可使得请求数据与解析一体化更方便,Android端还会自动将回调执行在主线程可以直接修改UI,新版的Retrofit还集成了Kotlin协程,更是利用协程解决了接口请求回调地狱的问题。

1.2 Retrofit的使用

  1. 添加依赖
implementation 'com.squareup.retrofit2:retrofit:2.9.0' 
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
  1. 定义接口请求和解析的实体类
/**
 * 接口服务
 * @author LTP  2023/7/18
 */
interface Api {
    /** 获取首页banner数据(协程方式返回无包装的实体) */
    @GET("banner/json")
    suspend fun getBanner(): ApiResponse<List<Banner>>

    /** 获取首页banner数据(使用协程返回Response包装的实体) */
    @GET("banner/json")
    suspend fun getBanner2(): Response<ApiResponse<List<Banner>>>

    /** 获取首页banner数据(普通方式返回Call包装的实体) */
    @GET("banner/json")
    fun getBanner3(): Call<ApiResponse<List<Banner>>>
}
/**
 * 接口返回外层封装实体
 *
 * @author LTP  2022/3/22
 */
data class ApiResponse<T>(
    val data: T,
    val errorCode: Int,
    val errorMsg: String
)
/**
 * 轮播图实体
 *
 * @author LTP  2022/3/22
 */
data class Banner(
    var desc: String = "",
    var id: Int = 0,
    var imagePath: String = "",
    var isVisible: Int = 0,
    var order: Int = 0,
    var title: String = "",
    var type: Int = 0,
    var url: String = ""
)
  1. 创建Retrofit对象,开启请求
/**
 * Retrofit请求网络测试类
 * @author LTP  2023/7/17
 */
class RetrofitUnitTest {

    /**创建retrofit对象 */
    private val retrofit = Retrofit.Builder().baseUrl("https://www.wanandroid.com")
        .addConverterFactory(GsonConverterFactory.create())
        .build()

    @Test
    fun getBanner() {
        val api = retrofit.create(Api::class.java)
        // runBlocking启动的协程会阻塞线程
        runBlocking {
            val response = api.getBanner()
            println(response)

            val response2 = api.getBanner2()
            println(response2.body())
        }

        // Retrofit异步请求
        api.getBanner3().enqueue(object : Callback<ApiResponse<List<Banner>>> {
            override fun onResponse(
                call: Call<ApiResponse<List<Banner>>>,
                response: Response<ApiResponse<List<Banner>>>
            ) {
                println(response)
            }

            override fun onFailure(call: Call<ApiResponse<List<Banner>>>, t: Throwable) {
            }
        })
        // 异步请求需要阻塞住主线程以等待请求完毕
        Thread.sleep(5000)

        // Retrofit同步请求
        val response = api.getBanner3().execute()
        println(response)
    }
}
  • 整个过程非常简单舒适,当然,Retrofit还可以进行更多的复杂操作,如配置请求头、请求提、表单提交等,可以直接看官网,这里就不再赘述了,直接看下整个请求过程

2. 源码解析

2.1 Retrofit对象的创建

  • 创建方式为:Retrofit.Builder().build(),一看就是Builder设计模式了,先看下Retrofit中的几个成员变量
public final class Retrofit {
  /** 主要用来缓存请求方法 */
  private final Map<Method, ServiceMethod<?>> serviceMethodCache = new ConcurrentHashMap<>();

  /** okhttp3.Call.Factory接口的实现类(OkHttpClient是唯一实现类) */
  final okhttp3.Call.Factory callFactory;
  /** 服务器根路径(当包含路径时必须以/结尾) */
  final HttpUrl baseUrl;
  /** 请求响应数据解析器集合(如GsonConverterFactory.create()) */
  final List<Converter.Factory> converterFactories;
  /** 网络请求适配器工厂集合,用于放置我们的网络请求适配器工厂(网络请求适配器:把我们的call对象转换成其他类型)
   * 如RxJavaCallAdapterFactory
   */
  final List<CallAdapter.Factory> callAdapterFactories;
  /** 用于回调执行(如Android中是MainThreadExecutor即主线程执行) */
  final @Nullable Executor callbackExecutor;
  /** 标志位,控制 Retrofit 是否立即验证 HTTP 请求和响应,以确保它们的正确性和完整性 */
  final boolean validateEagerly;
  ...
  • 直接看Builder模式最关键的方法build(),主要是针对成员进行组装判断,最终构造Retrofit对象
// Retrofit.java
public Retrofit build() {
  if (baseUrl == null) {
    throw new IllegalStateException("Base URL required.");
  }

  // 设置OkHttp中Call的工厂类(OkHttpClient是唯一实现类)
  okhttp3.Call.Factory callFactory = this.callFactory;
  if (callFactory == null) {
    // 没有设置的话使用默认的OkHttpClient对象
    callFactory = new OkHttpClient();
  }

  // 执行请求回调的对象,Android中defaultCallbackExecutor是MainThreadExecutor即主线程
  Executor callbackExecutor = this.callbackExecutor;
  if (callbackExecutor == null) {
    callbackExecutor = platform.defaultCallbackExecutor();
  }

  // 网络请求适配器工厂集合
  List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
  callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));

  // 数据转换器工厂集合(网络请求返回数据解析)
  List<Converter.Factory> converterFactories =
      new ArrayList<>(
          1 + this.converterFactories.size() + platform.defaultConverterFactoriesSize());

  // 先添加内置转换器工厂BuiltInConverters,主要包含一些基本类型(如
  // String:将响应数据转换为 String 类型、Integer、Long、Float、Double、Boolean、Character)的转换
  converterFactories.add(new BuiltInConverters());
  converterFactories.addAll(this.converterFactories);
  converterFactories.addAll(platform.defaultConverterFactories());

  return new Retrofit(
      callFactory,
      baseUrl,
      unmodifiableList(converterFactories),
      unmodifiableList(callAdapterFactories),
      callbackExecutor,
      validateEagerly);
}
  • 着重看下几个注意的点
  • baseUrl中包含路径时必须以/结尾
public Builder baseUrl(URL baseUrl) {
  Objects.requireNonNull(baseUrl, "baseUrl == null");
  return baseUrl(HttpUrl.get(baseUrl.toString()));
}

public Builder baseUrl(String baseUrl) {
  Objects.requireNonNull(baseUrl, "baseUrl == null");
  return baseUrl(HttpUrl.get(baseUrl));
}

public Builder baseUrl(HttpUrl baseUrl) {
  Objects.requireNonNull(baseUrl, "baseUrl == null");
  List<String> pathSegments = baseUrl.pathSegments();
  // 当baseUrl是一个域名加路径但路径最后一个字符不是以'/'结尾抛异常
  // 如https://www.wanandroid.com/api不行,必须为https://www.wanandroid.com/api/
  if (!"".equals(pathSegments.get(pathSegments.size() - 1))) {
    throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl);
  }
  this.baseUrl = baseUrl;
  return this;
}
  • platform.defaultCallbackExecutor()中platform是在Builder构造中通过Platform.get()获取的,看下这个Platform
/** 平台类(Android平台和Java平台) */
class Platform {
  private static final Platform PLATFORM = findPlatform();

  static Platform get() {
    return PLATFORM;
  }

  /**
   * 判断当前平台是Android还是Java
   * @return 平台类型
   */
  private static Platform findPlatform() {
    return "Dalvik".equals(System.getProperty("java.vm.name"))
        ? new Android() //
        : new Platform(true);
  }

 ...
 
  /** Android平台 */
  static final class Android extends Platform {
    Android() {
      super(Build.VERSION.SDK_INT >= 24);
    }

    /** Android平台下默认的callbackExecutor是MainThreadExecutor,即主线程 */
    @Override
    public Executor defaultCallbackExecutor() {
      return new MainThreadExecutor();
    }

    ...

    static final class MainThreadExecutor implements Executor {
      // 子线程到主线程还是通过Handler来切换线程的
      private final Handler handler = new Handler(Looper.getMainLooper());

      @Override
      public void execute(Runnable r) {
        handler.post(r);
      }
    }
  }
}
  • addConverterFactory:添加响应数据转换工厂,在build()方法中已添加默认的BuiltInConverters转换器,可针对一些常见类型(如服务器接口返回String、Integer、Long、Float、Double、Boolean、Character)进行转换,但通常服务器返回的是更复杂的数据类型,譬如Json数据、xml数据,而针对这种数据,Retrofit也提供了通用的一些转换插件(如converter-gson、converter-simplexml、converter-moshi等),这里以converter-gson为例
private val retrofit = Retrofit.Builder().baseUrl("https://www.wanandroid.com")
    .addConverterFactory(GsonConverterFactory.create())  // 添加GsonConverter
    .build()
  • 在covert-gson插件中看下GsonConverterFactory.create()方法
public final class GsonConverterFactory extends Converter.Factory {
 
  public static GsonConverterFactory create() {
    return create(new Gson());
  }

  @SuppressWarnings("ConstantConditions") 
  public static GsonConverterFactory create(Gson gson) {
    if (gson == null) throw new NullPointerException("gson == null");
    return new GsonConverterFactory(gson);
  }

  private final Gson gson;

  private GsonConverterFactory(Gson gson) {
    this.gson = gson;
  }

  @Override
  public Converter<ResponseBody, ?> responseBodyConverter(
      Type type, Annotation[] annotations, Retrofit retrofit) {
    TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
    return new GsonResponseBodyConverter<>(gson, adapter);
  }

  @Override
  public Converter<?, RequestBody> requestBodyConverter(
      Type type,
      Annotation[] parameterAnnotations,
      Annotation[] methodAnnotations,
      Retrofit retrofit) {
    TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
    return new GsonRequestBodyConverter<>(gson, adapter);
  }
}
  • 主要是继承了Converter.Factory抽象类,实现请求和响应转换方法,当然你也可以通过继承Converter.Factory抽象类来实现自定义请求响应转换器

2.2 网络请求

2.2.1 retrofit.create()

  • 从关键代码retrofit.create(Api::class.java)方法看起
// Retrofit.java
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 {
              // 如果方法是Object类中的方法,直接正常调用即可,无需代理
              if (method.getDeclaringClass() == Object.class) {
                return method.invoke(this, args);
              }
              args = args != null ? args : emptyArgs;
              // 这里判断了是否是默认方法(java8接口新增了默认方法),不是就调用loadServiceMethod
              return platform.isDefaultMethod(method)
                  ? platform.invokeDefaultMethod(method, service, proxy, args)
                  : loadServiceMethod(method).invoke(args); 
            }
          });
}
  • 这是一个典型的动态代理设计模式,代理返回一个Api实现类,调用api.getBanner就会去执行invoke方法,直接看invoke方法,忽略掉特殊情况(Object类的方法、java8接口的默认方法),最后调用的是loadServiceMethod(method).invoke(args),其中method表示getBanner接口方法
// Retrofit.java
/**
 * 加载数据请求服务的方法(由于解析会用到反射,加载后会存入缓存提升性能)
 * @param method Method
 * @return 请求服务的方法
 */
ServiceMethod<?> loadServiceMethod(Method method) {
  // 从缓存获取有就直接返回
  ServiceMethod<?> result = serviceMethodCache.get(method);
  if (result != null) return result;

  synchronized (serviceMethodCache) {
    result = serviceMethodCache.get(method);
    if (result == null) {
      // 缓存中没有,进行解析,返回的同时插入缓存
      result = ServiceMethod.parseAnnotations(this, method);
      serviceMethodCache.put(method, result);
    }
  }
  return result;
}
  • 主要使用了缓存策略,避免请求方法的多次解析,提高效率,直接看解析的方法ServiceMethod.parseAnnotations(this, method)
abstract class ServiceMethod<T> {
  static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
    // 这里会创建一个封装了OkHttp.Request的请求对象
    RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);

    // 获取请求服务的返回值,校验合法性
    Type returnType = method.getGenericReturnType();
    if (Utils.hasUnresolvableType(returnType)) {
      throw methodError(
          method,
          "Method return type must not include a type variable or wildcard: %s",
          returnType);
    }
    if (returnType == void.class) {
      throw methodError(method, "Service methods cannot return void.");
    }

    // 请求方法的解析(解析注解)
    return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
  }

  abstract @Nullable T invoke(Object[] args);
}
  • RequestFactory是对OkHttp.Request请求的封装,后面再深入源码,先一路深入,看下HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory)这个方法
abstract class HttpServiceMethod<ResponseT, ReturnT> extends ServiceMethod<ReturnT> {
  /** 检查接口方法上的注释,以构造一个可重复使用的HTTP服务方法。需要通过反射,所以需要使用缓存进行重用 */
static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
    Retrofit retrofit, Method method, RequestFactory requestFactory) {
  /** 是否是协程调用 */
  boolean isKotlinSuspendFunction = requestFactory.isKotlinSuspendFunction;
  /** 协程返回是否是Response包装实体 */
  boolean continuationWantsResponse = false;
  /** 协程返回是否是null */
  boolean continuationBodyNullable = false;

  // 解析方法上的所有注解
  Annotation[] annotations = method.getAnnotations();
  Type adapterType;
  if (isKotlinSuspendFunction) {
    Type[] parameterTypes = method.getGenericParameterTypes();
    Type responseType =
        Utils.getParameterLowerBound(
            0, (ParameterizedType) parameterTypes[parameterTypes.length - 1]);
    if (getRawType(responseType) == Response.class && responseType instanceof ParameterizedType) {
      // 这里判断协程的返回是否是一个Response,即判断是一个Response包装实体
      responseType = Utils.getParameterUpperBound(0, (ParameterizedType) responseType);
      continuationWantsResponse = true;
    } else {
    }

    adapterType = new Utils.ParameterizedTypeImpl(null, Call.class, responseType);
    annotations = SkipCallbackExecutorImpl.ensurePresent(annotations);
  } else {
    // 获取方法返回类型
    adapterType = method.getGenericReturnType();
  }

  // 获取CallAdapter,分析可发现这里最后返回的是DefaultCallAdapterFactory
  CallAdapter<ResponseT, ReturnT> callAdapter =
      createCallAdapter(retrofit, method, adapterType, annotations);
  Type responseType = callAdapter.responseType();
  // 返回类型的校验
  // 返回类型不能为okhttp3.Response类型
  if (responseType == okhttp3.Response.class) {
    throw methodError(
        method,
        "'"
            + getRawType(responseType).getName()
            + "' is not a valid response body type. Did you mean ResponseBody?");
  }
  // 返回类型不能是Response,必须要包含泛型才行,类似于Response<String>
  if (responseType == Response.class) {
    throw methodError(method, "Response must include generic type (e.g., Response<String>)");
  }
  // TODO support Unit for Kotlin?
  if (requestFactory.httpMethod.equals("HEAD") && !Void.class.equals(responseType)) {
    throw methodError(method, "HEAD method must use Void as response type.");
  }

  // 获取Convert对象,自带的是BuiltInConverters,我们传入了GsonConverterFactory
  Converter<ResponseBody, ResponseT> responseConverter =
      createResponseConverter(retrofit, method, responseType);

  // 获取一个okhttp3.Call.Factory对象,其实就是OkHttpClient对象
  okhttp3.Call.Factory callFactory = retrofit.callFactory;
  if (!isKotlinSuspendFunction) {
    // 不是Kotlin协程的suspend方法
    // 返回一个新建的CallAdapted对象,传入requestFactory, callFactory, responseConverter, callAdapter
    return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
  } else if (continuationWantsResponse) {
    // 协程返回类型是Response<T>
    return (HttpServiceMethod<ResponseT, ReturnT>)
        new SuspendForResponse<>(
            requestFactory,
            callFactory,
            responseConverter,
            (CallAdapter<ResponseT, Call<ResponseT>>) callAdapter);
  } else {
    // 协程返回类型是 T
    return (HttpServiceMethod<ResponseT, ReturnT>)
        new SuspendForBody<>(
            requestFactory,
            callFactory,
            responseConverter,
            (CallAdapter<ResponseT, Call<ResponseT>>) callAdapter,
            continuationBodyNullable);
  }
}
  • 直接看最后的返回,不是协程时返回的是CallAdapted对象,协程时当请求suspend函数返回的是Response时,返回SuspendForResponse对象,协程直接返回实体T时返回SuspendForBody
  • 参数中requestFactory, callFactory, responseConverter, callAdapter均比较重要后面再逐个分析
  • 追了这么久的返回值,最开始是从loadServiceMethod(method).invoke(args)调用的,loadServiceMethod(method)返回的是CallAdapted/SuspendForResponse/SuspendForBody,所以最后分别是这三个对象调用了invoke(),先看不是协程时callAdapted.invoke()
static final class CallAdapted<ResponseT, ReturnT> extends HttpServiceMethod<ResponseT, ReturnT> {
  private final CallAdapter<ResponseT, ReturnT> callAdapter;

  CallAdapted(
      RequestFactory requestFactory,
      okhttp3.Call.Factory callFactory,
      Converter<ResponseBody, ResponseT> responseConverter,
      CallAdapter<ResponseT, ReturnT> callAdapter) {
    super(requestFactory, callFactory, responseConverter);
    this.callAdapter = callAdapter;
  }

  @Override
  protected ReturnT adapt(Call<ResponseT> call, Object[] args) {
    return callAdapter.adapt(call);
  }
}
  • 没看到有invoke()方法,向他的父类继续寻找
abstract class HttpServiceMethod<ResponseT, ReturnT> extends ServiceMethod<ReturnT> {
    ...
    @Override
    final @Nullable ReturnT invoke(Object[] args) {
      Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
      return adapt(call, args);
    }
    
    protected abstract @Nullable ReturnT adapt(Call<ResponseT> call, Object[] args);
    ...
}
  • 父类的invoke()调用了抽象方法adapt(call,args),这个call是一个OkHttpCall本质上是okhttp3.Call的扩展,先放着后面再探讨,adapt这个抽象方法再在子类CallAdapted中被重写,所以最终会执行CallAdapted自身的adapt(),而上面CallAdapted类的adapt方法最终执行的是callAdapter.adapt(call),接下来就要分析下之前遗留的四个参数中的callAdapter了

2.2.2 CallAdapter

  • CallAdapter是一个接口,主要用于创建 Call 对象,并指定如何处理异步请求和响应,例如自身默认的DefaultCallAdapterFactory和插件RxJavaCallAdapter都是它的实现
public interface CallAdapter<R, T> {
  Type responseType();

  T adapt(Call<R> call);

  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);
    }
  }
}
  • 追一下刚刚CallAdapted类中的callAdapter,是在HttpServiceMethod.parseAnnotations()方法中获取并通过CallAdapted构造传入的
abstract class HttpServiceMethod<ResponseT, ReturnT> extends ServiceMethod<ReturnT> {
  /**
   * 检查接口方法上的注释,以构造一个可重复使用的HTTP服务方法。需要通过反射,所以需要使用缓存进行重用
   */
  static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
      Retrofit retrofit, Method method, RequestFactory requestFactory) {
     ...

    // 注释1
    // 获取CallAdapter,分析可发现这里最后返回的是DefaultCallAdapterFactory
    CallAdapter<ResponseT, ReturnT> callAdapter =
        createCallAdapter(retrofit, method, adapterType, annotations);
   
    ...
    if (!isKotlinSuspendFunction) {
      // 不是Kotlin协程的suspend方法
      // 返回一个新建的CallAdapted对象,传入requestFactory, callFactory, responseConverter, callAdapter
      return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
    } else if (continuationWantsResponse) {
      return (HttpServiceMethod<ResponseT, ReturnT>)
          new SuspendForResponse<>(
              requestFactory,
              callFactory,
              responseConverter,
              (CallAdapter<ResponseT, Call<ResponseT>>) callAdapter);
    } else {
      return (HttpServiceMethod<ResponseT, ReturnT>)
          new SuspendForBody<>(
              requestFactory,
              callFactory,
              responseConverter,
              (CallAdapter<ResponseT, Call<ResponseT>>) callAdapter,
              continuationBodyNullable);
    }
  }
  • 从上面的注释1得知callAdapter是由createCallAdapter方法返回的
// HttpServiceMethod.java
private static <ResponseT, ReturnT> CallAdapter<ResponseT, ReturnT> createCallAdapter(
    Retrofit retrofit, Method method, Type returnType, Annotation[] annotations) {
  try {
    return (CallAdapter<ResponseT, ReturnT>) retrofit.callAdapter(returnType, annotations);
  } catch (RuntimeException e) { 
    throw methodError(method, e, "Unable to create call adapter for %s", returnType);
  }
}
  • 最终从retrofit.callAdapter()获取
public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) {
  return nextCallAdapter(null, returnType, annotations);
}
    

public CallAdapter<?, ?> nextCallAdapter(
    @Nullable CallAdapter.Factory skipPast, Type returnType, Annotation[] annotations) {
  ...
  int start = callAdapterFactories.indexOf(skipPast) + 1;
  for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
    CallAdapter<?, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this);
    if (adapter != null) {
      return adapter;
    }
  }
  ...
}
  • 最终是获取的callAdapterFactories中配置的callAdapterFactory,在2.2.1 Retrofit对象的创建中 得知,默认会添加DefaultCallAdapterFactory
final class DefaultCallAdapterFactory extends CallAdapter.Factory {
  private final @Nullable Executor callbackExecutor;

  DefaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
    this.callbackExecutor = callbackExecutor;
  }

  @Override
  public @Nullable CallAdapter<?, ?> get(
      Type returnType, Annotation[] annotations, Retrofit retrofit) {
    if (getRawType(returnType) != Call.class) {
      return null;
    }
    if (!(returnType instanceof ParameterizedType)) {
      throw new IllegalArgumentException(
          "Call return type must be parameterized as Call<Foo> or Call<? extends Foo>");
    }
    final Type responseType = Utils.getParameterUpperBound(0, (ParameterizedType) returnType);

    // 注释1
   // 判断请求方法上是否有@SkipCallbackExecutor注解,有返回null,没有返回callbackExecutor
// 注意默认情况下callbackExecutor在Java平台也是null,而在Android平台返回MainThreadExecutor
    final Executor executor =
        Utils.isAnnotationPresent(annotations, SkipCallbackExecutor.class)
            ? null
            : callbackExecutor;

    // 返回CallAdapter的匿名实现类  注释2
    return new CallAdapter<Object, Call<?>>() {
      @Override
      public Type responseType() {
        return responseType;
      }

      @Override
      public Call<Object> adapt(Call<Object> call) {
        // 最终会调用这里 注释3
        return executor == null ? call : new ExecutorCallbackCall<>(executor, call);
      }
    };
  }

  static final class ExecutorCallbackCall<T> implements Call<T> {
    final Executor callbackExecutor;
    final Call<T> delegate;

    ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) {
      this.callbackExecutor = callbackExecutor;
      this.delegate = delegate;
    }

    @Override
    public void enqueue(final Callback<T> callback) {
      Objects.requireNonNull(callback, "callback == null");

      delegate.enqueue(
          new Callback<T>() {
            @Override
            public void onResponse(Call<T> call, final Response<T> response) {
              callbackExecutor.execute(
                  () -> {
                    if (delegate.isCanceled()) {
                      callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled"));
                    } else {
                      callback.onResponse(ExecutorCallbackCall.this, response);
                    }
                  });
            }

            @Override
            public void onFailure(Call<T> call, final Throwable t) {
              callbackExecutor.execute(() -> callback.onFailure(ExecutorCallbackCall.this, t));
            }
          });
    }

   ...
  }
}
  • 从上面得之CallAdapter是从DefaultCallAdapterFactory.get()返回的,从上面代码的注释1可得知返回的是一个匿名CallAdapter实现类,从2.2.1得知最后走的是CallAdapter.adapt()方法,所以这里最终会执行这个匿名CallAdapter实现类的重写方法adapt()
  • 在adapt()方法里(注释3)中,会对executor进行判断,如果为null直接返回call,即上面分析的OkHttpCall,否则返回ExecutorCallbackCall;至于这个excutor则是在注释1处进行判断的,通过判断请求方法中是否包含@SkipCallbackExecutor注解,如果有就返回null,没有就返回callbackExecutorcallbackExecutor默认情况下在Java平台返回null而Android平台会返回MainThreadExecutor
final class DefaultCallAdapterFactory extends CallAdapter.Factory {
  private final @Nullable Executor callbackExecutor;

  DefaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
    this.callbackExecutor = callbackExecutor;
  }
  ...
}        
class Platform {
 ...
    
  @Nullable
  Executor defaultCallbackExecutor() {
    return null;
  }

  List<? extends CallAdapter.Factory> defaultCallAdapterFactories(
      @Nullable Executor callbackExecutor) {
    // callbackExecutor是从这里传入的
    DefaultCallAdapterFactory executorFactory = new DefaultCallAdapterFactory(callbackExecutor);
    return hasJava8Types
        ? asList(CompletableFutureCallAdapterFactory.INSTANCE, executorFactory)
        : singletonList(executorFactory);
  }
...

static final class Android extends Platform {

  @Override
  public Executor defaultCallbackExecutor() {
    return new MainThreadExecutor();
  }
...
}
  • callbackExecutor是从PlatForm.defaultCallAdapterFactories()传入的,继续追这个方法的调用
public final class Retrofit {
...
  public static final class Builder {
    ...
    public Retrofit build() {
      ...
      // 执行请求回调的对象,Android中defaultCallbackExecutor是MainThreadExecutor即主线程
      Executor callbackExecutor = this.callbackExecutor;
      if (callbackExecutor == null) {
        // 注释1
        callbackExecutor = platform.defaultCallbackExecutor();
      }

      // 网络请求适配器工厂集合
      List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
      callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));
      ...
    }
  }
}
  • 由上面的注释1可得最终是获取得platform.defaultCallbackExecutor(),这就证明了上面得结论:默认情况下在Java平台返回null而Android平台会返回MainThreadExecutor,也就是Java平台最终会返回OkhttpCall,Android平台返回ExecutorCallbackCall

2.2.3 OkhttpCall & ExecutorCallbackCall

  • 先看下这个OkhttpCall,它可以理解为okhttp3.Call的封装
/** 对okhttp3.Call的封装 */
final class OkHttpCall<T> implements Call<T> {
  /** OkHttp的请求Request的封装 */
  private final RequestFactory requestFactory;
  private final Object[] args;
  /** okhttp3.Call.Factory可以理解为okhttpClient */
  private final okhttp3.Call.Factory callFactory;
  private final Converter<ResponseBody, T> responseConverter;

  private volatile boolean canceled;

  /** 持有对okhttp3.Call的引用 */
  @GuardedBy("this")
  private @Nullable okhttp3.Call rawCall;

  @GuardedBy("this") 
  private @Nullable Throwable creationFailure;

  /** 是否已经执行execute的标志位(是否已经在请求队列) */
  @GuardedBy("this")
  private boolean executed;

  OkHttpCall(
      RequestFactory requestFactory,
      Object[] args,
      okhttp3.Call.Factory callFactory,
      Converter<ResponseBody, T> responseConverter) {
    this.requestFactory = requestFactory;
    this.args = args;
    this.callFactory = callFactory;
    this.responseConverter = responseConverter;
  }

  ...

  /** 返回okhttp3.Call,有异常抛出 */
  @GuardedBy("this")
  private okhttp3.Call getRawCall() throws IOException {
    okhttp3.Call call = rawCall;
    if (call != null) return call;

    ...
    try {
      return rawCall = createRawCall();
    } catch (RuntimeException | Error | IOException e) {
      throwIfFatal(e); 
      creationFailure = e;
      throw e;
    }
  }

  /** 异步请求 */
  @Override
  public void enqueue(final Callback<T> callback) {
    Objects.requireNonNull(callback, "callback == null");

    okhttp3.Call call;
    Throwable failure;

    synchronized (this) {
      if (executed) throw new IllegalStateException("Already executed.");
      executed = true;

      call = rawCall;
      failure = creationFailure;
      if (call == null && failure == null) {
        try {
          // 构建okhttp.call 注释1
          call = rawCall = createRawCall();
        } catch (Throwable t) {
          throwIfFatal(t);
          failure = creationFailure = t;
        }
      }
    }

    if (failure != null) {
      callback.onFailure(this, failure);
      return;
    }

    if (canceled) {
      call.cancel();
    }

    call.enqueue(
        new okhttp3.Callback() {
          @Override
          public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
            Response<T> response;
            try {
              // 解析响应数据
              response = parseResponse(rawResponse);
            } catch (Throwable e) {
              throwIfFatal(e);
              callFailure(e);
              return;
            }

            try {
              callback.onResponse(OkHttpCall.this, response);
            } catch (Throwable t) {
              throwIfFatal(t);
              t.printStackTrace(); // TODO this is not great
            }
          }

          @Override
          public void onFailure(okhttp3.Call call, IOException e) {
            callFailure(e);
          }

          private void callFailure(Throwable e) {
            try {
              callback.onFailure(OkHttpCall.this, e);
            } catch (Throwable t) {
              throwIfFatal(t);
              t.printStackTrace(); // TODO this is not great
            }
          }
        });
  }

  /** 同步请求 */
  @Override
  public Response<T> execute() throws IOException {
    okhttp3.Call call;

    synchronized (this) {
      if (executed) throw new IllegalStateException("Already executed.");
      executed = true;

      call = getRawCall();
    }

    if (canceled) {
      call.cancel();
    }

    return parseResponse(call.execute());
  }

  /** 利用okhttpClient创建okhttp3.Call对象 */
  private okhttp3.Call createRawCall() throws IOException {
    // 注释2
    okhttp3.Call call = callFactory.newCall(requestFactory.create(args));
    if (call == null) {
      throw new NullPointerException("Call.Factory returned null.");
    }
    return call;
  }

  /** 负责请求响应的解析 */
  Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
    ResponseBody rawBody = rawResponse.body();

    ...
    ExceptionCatchingResponseBody catchingBody = new ExceptionCatchingResponseBody(rawBody);
    try {
      // 解析请求响应
      T body = responseConverter.convert(catchingBody);
      return Response.success(body, rawResponse);
     ...
  }

}
  • 回忆下Retrofit的请求步骤,从上文分析api.getBanner()返回的是一个OkhttpCall(Android平台是ExecutorCallbackCall,这个稍后分析),接下来的步骤就是通过异步调用okhttpCall.enqueue()或同步调用okhttpCall.execute(),我们直接看这两个方法
  • enqueue()中先在注释1处通过createRawCall()拿到okhttp.call,具体的方法就一行 okhttp3.Call call = callFactory.newCall(requestFactory.create(args)),这个callFactory就是okHttpClient,这也符合okHttp创建Call的步骤,所以参数中requestFactory.create(args)必然返回的是okhttp.Request,这个后面分析RequestFactory时再细讲
  • 按照okhttp的请求步骤,接着就是接管okhttp中call.enqueue()的请求回调,在成功回调中对响应数据进行解析后用自己的回调去响应即可,失败就原样回调接管返回,而同步请求execute()就直接解析就可以了
  • 接着看下ExecutorCallbackCall是个啥
static final class ExecutorCallbackCall<T> implements Call<T> {
  final Executor callbackExecutor;
  /** Call代理,这里传入的其实就是okHttpCall */
  final Call<T> delegate;

  ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) {
    this.callbackExecutor = callbackExecutor;
    this.delegate = delegate;
  }

  @Override
  public void enqueue(final Callback<T> callback) {
    Objects.requireNonNull(callback, "callback == null");

    delegate.enqueue(
        new Callback<T>() {
          @Override
          public void onResponse(Call<T> call, final Response<T> response) {
            callbackExecutor.execute(
                () -> {
                  if (delegate.isCanceled()) {
                    callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled"));
                  } else {
                    callback.onResponse(ExecutorCallbackCall.this, response);
                  }
                });
          }

          @Override
          public void onFailure(Call<T> call, final Throwable t) {
            callbackExecutor.execute(() -> callback.onFailure(ExecutorCallbackCall.this, t));
          }
        });
  }

  @Override
  public boolean isExecuted() {
    return delegate.isExecuted();
  }

  @Override
  public Response<T> execute() throws IOException {
    return delegate.execute();
  }

  @Override
  public void cancel() {
    delegate.cancel();
  }

  @Override
  public boolean isCanceled() {
    return delegate.isCanceled();
  }

  @SuppressWarnings("CloneDoesntCallSuperClone") 
  @Override
  public Call<T> clone() {
    return new ExecutorCallbackCall<>(callbackExecutor, delegate.clone());
  }

  @Override
  public Request request() {
    return delegate.request();
  }

  @Override
  public Timeout timeout() {
    return delegate.timeout();
  }
}
  • 其实就是用到了装饰器模式静态代理,在不改变OkhttpCall的情况下,其他方法均由okhttpCall这个代理对象进行操作,只对enqueue()方法使用callbackExecutor进行装饰,之前分析得到在Android平台callbackExecutor是一个MainThreadExecutor对象
// Platform.java
static final class MainThreadExecutor implements Executor {
  private final Handler handler = new Handler(Looper.getMainLooper());

  @Override
  public void execute(Runnable r) {
    handler.post(r);
  }
}
  • 其实就是在接口返回中使用Handler包装一层实现线程的切换(okhttp请求是单独开启线程的,回调也是发生在子线程的)这样更适合Android平台,方便请求后直接操作UI

2.2.4 RequestFactory

  • 刚刚上面说到会使用requestFactory.create(args)构造一个okhttp.Request对象,现在就来看下里面的魔法
/**
 * 请求封装,主要是将Retrofit的请求转换为OkHttp的请求
 */
final class RequestFactory {
    static RequestFactory parseAnnotations(Retrofit retrofit, Method method) {
        return new Builder(retrofit, method).build();
    }

    private final Method method;
    private final HttpUrl baseUrl;
    final String httpMethod;
    private final @Nullable String relativeUrl;
    private final @Nullable Headers headers;
    private final @Nullable MediaType contentType;
    private final boolean hasBody;
    private final boolean isFormEncoded;
    private final boolean isMultipart;
    private final ParameterHandler<?>[] parameterHandlers;
    /** 请求是否是一个Kotlin协程中的挂载函数 */
    final boolean isKotlinSuspendFunction;
    ...
}                                                                 
  • 第一个方法就是parseAnnotations()方法,就是在ServiceMethod.parseAnnotations()中调用的,主要还是用到了Builder模式来构建RequestFactory对象
  • RequestFactory中还包含一些请求相关的成员变量,例如请求地址、请求方法、请求头等,这里有一个isKotlinSuspendFunction变量主要是判断请求方法是否是一个Kotlin中的挂载函数,具体后面分析Kotlin协程返回再具体分析
  • 直接看requestFactory.create(args)看下它是如何构造出一个okhttp.Request对象的
/**
 * 创建okhttp3.Request对象
 * @param args
 * @return
 * @throws IOException
 */
okhttp3.Request create(Object[] args) throws IOException {
    @SuppressWarnings("unchecked") types.
    ParameterHandler<Object>[] handlers = (ParameterHandler<Object>[]) parameterHandlers;

    int argumentCount = args.length;
    if (argumentCount != handlers.length) {
        throw new IllegalArgumentException(
                "Argument count ("
                        + argumentCount
                        + ") doesn't match expected count ("
                        + handlers.length
                        + ")");
    }

    RequestBuilder requestBuilder =
            new RequestBuilder(
                    httpMethod,
                    baseUrl,
                    relativeUrl,
                    headers,
                    contentType,
                    hasBody,
                    isFormEncoded,
                    isMultipart);

    if (isKotlinSuspendFunction) {
        // kotlin挂载函数(suspend关键字)编译成class会比java多一个Continuation类型的参数,所以此处需要-1
        argumentCount--;
    }

    List<Object> argumentList = new ArrayList<>(argumentCount);
    for (int p = 0; p < argumentCount; p++) {
        argumentList.add(args[p]);
        handlers[p].apply(requestBuilder, args[p]);
    }

    return requestBuilder.get().tag(Invocation.class, new Invocation(method, argumentList)).build();
}
  • 主要是构造了一个RequestBuilder对象,并调用改对象的get()方法返回一个okHttp的Request.Builder对象,最后使用这个对象调用build()方法就可以构造出okhttp.Request对象了,我们看下这个RequestBuilder对象
final class RequestBuilder {
  private final String method;

  private final HttpUrl baseUrl;
  private @Nullable String relativeUrl;
  private @Nullable HttpUrl.Builder urlBuilder;

  private final Request.Builder requestBuilder;
  private final Headers.Builder headersBuilder;
  private @Nullable MediaType contentType;

  private final boolean hasBody;
  private @Nullable MultipartBody.Builder multipartBuilder;
  private @Nullable FormBody.Builder formBuilder;
  private @Nullable RequestBody body;
  ...
  Request.Builder get() {
      HttpUrl url;
      HttpUrl.Builder urlBuilder = this.urlBuilder;
      if (urlBuilder != null) {
        url = urlBuilder.build();
      } else {
        url = baseUrl.resolve(relativeUrl);
        if (url == null) {
          throw new IllegalArgumentException(
              "Malformed URL. Base: " + baseUrl + ", Relative: " + relativeUrl);
        }
      }

      RequestBody body = this.body;
      if (body == null) {
        // Try to pull from one of the builders.
        if (formBuilder != null) {
          body = formBuilder.build();
        } else if (multipartBuilder != null) {
          body = multipartBuilder.build();
        } else if (hasBody) {
          // Body is absent, make an empty body.
          body = RequestBody.create(null, new byte[0]);
        }
      }

      MediaType contentType = this.contentType;
      if (contentType != null) {
        if (body != null) {
          body = new ContentTypeOverridingRequestBody(body, contentType);
        } else {
          headersBuilder.add("Content-Type", contentType.toString());
        }
      }

      // 这里构建OkHttp.Request.Builder对象
      return requestBuilder.url(url).headers(headersBuilder.build()).method(method, body);
    }
  • 主要是挟持了okhttp的诸多对象,通过对请求方法中的注解的解析,最后包装成一个OkHttp.Request对象

2.2.5 Retrofit如何支持协程

  • 首先看下它是如何判断请求方法是一个Kotlin挂载(suspend)函数,我们先看下kotlin的suspend函数转变成Java的样子,找到刚刚的Api.kt编译后的class(build目录中),使用Android Studio自带的Kotlin工具Decompile to Java会编译成
public interface Api {
   @GET("banner/json")
   @Nullable
   Object getBanner(@NotNull Continuation var1);

   @GET("banner/json")
   @Nullable
   Object getBanner2(@NotNull Continuation var1);

   @GET("banner/json")
   @NotNull
   Call getBanner3();
}
  • 可见suspend方法比普通的Java方法多出一个Continuation参数(最后一个参数),看下Retrofit中是不是从这点来判断的
final class RequestFactory {
   ...
    /** 请求是否是一个Kotlin协程中的挂载函数 */
    final boolean isKotlinSuspendFunction;
    
    ```
 private @Nullable ParameterHandler<?> parseParameter(
        int p, Type parameterType, @Nullable Annotation[] annotations, boolean allowContinuation) {
    ParameterHandler<?> result = null;
    if (annotations != null) {
        for (Annotation annotation : annotations) {
            ParameterHandler<?> annotationAction =
                    parseParameterAnnotation(p, parameterType, annotations, annotation);

            if (annotationAction == null) {
                continue;
            }

            if (result != null) {
                throw parameterError(
                        method, p, "Multiple Retrofit annotations found, only one allowed.");
            }

            result = annotationAction;
        }
    }

    // 判断请求方法的最后一个参数是否是Continuation类型,是就是一个suspend函数
     if (result == null) {
        if (allowContinuation) {
            try {
                if (Utils.getRawType(parameterType) == Continuation.class) {
                    isKotlinSuspendFunction = true;
                    return null;
                }
            } catch (NoClassDefFoundError ignored) {
            }
        }
        throw parameterError(method, p, "No Retrofit annotation found.");
    }

    return result;
   }
...
}
  • 的确源码就是根据这个参数来判断的,看下parseAnnotations()中协程相关部分
// HttpServiceMethod.java
static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
    Retrofit retrofit, Method method, RequestFactory requestFactory) {
  /** 是否是协程调用 */
  boolean isKotlinSuspendFunction = requestFactory.isKotlinSuspendFunction;
  /** 协程返回是否是Response包装实体 */
  boolean continuationWantsResponse = false;
  /** 协程返回是否是null */
  boolean continuationBodyNullable = false;

  ...
  if (!isKotlinSuspendFunction) {
    // 不是Kotlin协程的suspend方法
    // 返回一个新建的CallAdapted对象,传入requestFactory, callFactory, responseConverter, callAdapter
    return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
  } else if (continuationWantsResponse) {
    return (HttpServiceMethod<ResponseT, ReturnT>)
        new SuspendForResponse<>(
            requestFactory,
            callFactory,
            responseConverter,
            (CallAdapter<ResponseT, Call<ResponseT>>) callAdapter);
  } else {
    return (HttpServiceMethod<ResponseT, ReturnT>)
        new SuspendForBody<>(
            requestFactory,
            callFactory,
            responseConverter,
            (CallAdapter<ResponseT, Call<ResponseT>>) callAdapter,
            continuationBodyNullable);
  }
}
  • 这里的isKotlinSuspendFunction就是从requestFactory获取的,当为协程时,判断请求返回类型是Response还是T,这里就以T为例,最终返回的是一个SuspendForBody对象
static final class SuspendForBody<ResponseT> extends HttpServiceMethod<ResponseT, Object> {
  private final CallAdapter<ResponseT, Call<ResponseT>> callAdapter;
  private final boolean isNullable;

  SuspendForBody(
      RequestFactory requestFactory,
      okhttp3.Call.Factory callFactory,
      Converter<ResponseBody, ResponseT> responseConverter,
      CallAdapter<ResponseT, Call<ResponseT>> callAdapter,
      boolean isNullable) {
    super(requestFactory, callFactory, responseConverter);
    this.callAdapter = callAdapter;
    this.isNullable = isNullable;
  }

  @Override
  protected Object adapt(Call<ResponseT> call, Object[] args) {
    call = callAdapter.adapt(call);

    Continuation<ResponseT> continuation = (Continuation<ResponseT>) args[args.length - 1];

    try {
      return isNullable
          ? KotlinExtensions.awaitNullable(call, continuation)
          : KotlinExtensions.await(call, continuation);
    } catch (Exception e) {
      return KotlinExtensions.suspendAndThrow(e, continuation);
    }
  }
}
  • 按照上一篇的分析,最终会执行adapt方法,这个isNullable是从上面parseAnnotations()方法中的continuationBodyNullable传递的,为false,所以最终会执行KotlinExtensions.await(call, continuation)
/** Call的扩展函数 */
suspend fun <T : Any> Call<T>.await(): T {
  return suspendCancellableCoroutine { continuation ->
    continuation.invokeOnCancellation {
      cancel()
    }
    enqueue(object : Callback<T> {
      override fun onResponse(call: Call<T>, response: Response<T>) {
        if (response.isSuccessful) {
          val body = response.body()
          if (body == null) {
            val invocation = call.request().tag(Invocation::class.java)!!
            val method = invocation.method()
            val e = KotlinNullPointerException("Response from " +
                method.declaringClass.name +
                '.' +
                method.name +
                " was null but response body type was declared as non-null")
            // 协程返回请求错误
            continuation.resumeWithException(e)
          } else {
            // 协程返回
            continuation.resume(body)
          }
        } else {
          continuation.resumeWithException(HttpException(response))
        }
      }

      override fun onFailure(call: Call<T>, t: Throwable) {
        continuation.resumeWithException(t)
      }
    })
  }
}
  • 就是利用kotlin的高阶函数给Call添加一个await扩展函数,再在onResponse回调中,通过协程挂起来执行耗时任务,而成功与失败会分别通过resume()resumeWithExecption()来唤起挂起的协程,让它返回之前的挂起点,进行执行

2.3 流程图和类图

  • 大致流程图 Retrofit源码阅读

  • 类图 Retrofit源码阅读

2.4 Retrofit使用的设计模式

2.4.1 Builder模式

  • 关于Builder模式,可以看下设计模式~Builder模式
  • Retrofit中使用Builder模式的地方,大概有Retrofit对象的构建RequestFactory对象的构建

2.4.2 代理模式

  • Retrofit中的核心就是使用到了代理模式,包含通过动态代理将每一个请求方法构建成OkHttpCall
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.
              // 如果方法是Object类中的方法,直接正常调用即可,无需代理
              if (method.getDeclaringClass() == Object.class) {
                return method.invoke(this, args);
              }
              args = args != null ? args : emptyArgs;
              // 这里判断了是否是默认方法(java8接口新增了默认方法),不是就调用loadServiceMethod
              return platform.isDefaultMethod(method)
                  ? platform.invokeDefaultMethod(method, service, proxy, args)
                  : loadServiceMethod(method).invoke(args);
            }
          });
}
  • Retrofit中也使用了静态代理,ExecutorCallbackCall中,使用delegate(OkHttpCall)静态代理执行了Call的一些抽象方法,而无需自行实现
// DefaultCallAdapterFactory.java
static final class ExecutorCallbackCall<T> implements Call<T> {
  final Executor callbackExecutor;
  /** Call代理,这里传入的其实就是okHttpCall */
  final Call<T> delegate;

  ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) {
    this.callbackExecutor = callbackExecutor;
    this.delegate = delegate;
  }

  @Override
  public void enqueue(final Callback<T> callback) {
    Objects.requireNonNull(callback, "callback == null");

    delegate.enqueue(
        new Callback<T>() {
          @Override
          public void onResponse(Call<T> call, final Response<T> response) {
            callbackExecutor.execute(
                () -> {
                  if (delegate.isCanceled()) {
                    // Emulate OkHttp's behavior of throwing/delivering an IOException on
                    // cancellation.
                    callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled"));
                  } else {
                    callback.onResponse(ExecutorCallbackCall.this, response);
                  }
                });
          }

          @Override
          public void onFailure(Call<T> call, final Throwable t) {
            callbackExecutor.execute(() -> callback.onFailure(ExecutorCallbackCall.this, t));
          }
        });
  }

  @Override
  public boolean isExecuted() {
    return delegate.isExecuted();
  }

  @Override
  public Response<T> execute() throws IOException {
    return delegate.execute();
  }

  @Override
  public void cancel() {
    delegate.cancel();
  }

  @Override
  public boolean isCanceled() {
    return delegate.isCanceled();
  }

  @SuppressWarnings("CloneDoesntCallSuperClone") // Performing deep clone.
  @Override
  public Call<T> clone() {
    return new ExecutorCallbackCall<>(callbackExecutor, delegate.clone());
  }

  @Override
  public Request request() {
    return delegate.request();
  }

  @Override
  public Timeout timeout() {
    return delegate.timeout();
  }
}

2.4.3 装饰模式

  • 设计模式~装饰模式 - 掘金 (juejin.cn)
  • 上面的ExecutorCallbackCall其实也是一个装饰模式,对Call的其他实现类进行装饰,这里真正去执行请求的是OkHttpCall。之所以要有个装饰类,是希望做一些额外操作。这里的操作就是线程转换,将子线程切换到主线程上去,没有直接继承OkHttpCall是这样能降低ExecutorCallbackCall与OkHttpCall的耦合度

2.4.4 策略模式

  • 策略模式定义了一组算法,将每个算法都封装起来,并且使它们之间可以互换。
  1. 在CallAdapter中可以添加多个CallAdapte.Factory对象,相当于我们封装了多个不同的适配算法CallAdapter.adapt();如系统默认的DefaultCallAdapterFactory和插件RxJava2CallAdapterFactory等
  2. 在Converter中可以添加多个Converter.Factory对象,相当于我们封装了多个不同的请求响应解析算法Converter.convert();如系统默认的BuiltInConverters和插件GsonConverterFactory等

2.4.5 外观模式

  • 我们在HTTP API接口中定义了很多方法,参数都在方法上进行定义,只会告诉调用者需要传入哪些参数,具体的操作并不向外暴露,这个就是外观模式
interface Api {

    /** 获取首页banner数据(普通方式返回Call包装的实体) */
    @GET("banner/json")
    fun getBanner(): Call<ApiResponse<List<Banner>>>
}

val api = retrofit.create(Api::class.java)
val call:Call<ApiResponse<List<Banner>>> = api.getBanner()

2.4.6 适配器模式

  • Retrofit中,CallAdapter就采用了适配器模式为创建访问Call接口提供服务。默认情况下使用默认的 ExecutorCallAdapterFactory 将okhttp3.call转变成为 retroift中的call,如果设定RxJava,则将okhttp3.call转化为 Observable