Retrofit2.0 源码解析笔记

主要参考文章:

  1. Android网络编程(十一)源码解析Retrofit
  2. Android:手把手带你 深入读懂 Retrofit 2.0 源码

对应的源码版本如下:

'com.squareup.retrofit2:retrofit:2.5.0'

// 并且引入了 GsonConverter 与 RxJavaCallAdapter
'com.squareup.retrofit2:converter-gson:2.5.0'
'com.squareup.retrofit2:adapter-rxjava:2.5.0'

辅助讲解用的示例代码为 Kotlin 版本的。


第一部分

1、retrofit 的实例化

首先需要弄清楚这段代码的作用,即 retrofit 是怎么实例化的。

val retrofit = Retrofit.Builder()
        .baseUrl("http://fy.iciba.com/")
        // 设置 CallAdapterFactory 到 Retrofit 的 callAdapterFactories 中
        .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
        // 设置 ConverterFactory 到 Retrofit 的 converterFactories 中
        .addConverterFactory(GsonConverterFactory.create())
        // 通过构建者模式实例出 retrofit
        .build()

Builder 的无参构造方法如下:

public Builder() {
  this(Platform.get());
}

这里,涉及到了一个平台(Platform) 的概念。

class Platform {
  private static final Platform PLATFORM = findPlatform();
  // get() 方法会根据当前环境得到对应的 Platform
  static Platform get() {
    return PLATFORM;
  }
  private static Platform findPlatform() {
    try {
      Class.forName("android.os.Build");
      if (Build.VERSION.SDK_INT != 0) {
        return new Android();
      }
    } catch (ClassNotFoundException ignored) {
    }
    try {
      Class.forName("java.util.Optional");
      return new Java8();
    } catch (ClassNotFoundException ignored) {
    }
    return new Platform();
  }
  ...
}

一共有三种类型的 Platform,即 AndroidJava8,以及 Platform 自身(另外两种继承自它)。因此,可以知道 Retrofit 不仅仅是能在 Android 中使用,在正常的 Java8 中也能够使用。

static class Android extends Platform {
  ...
  
  @Override public Executor defaultCallbackExecutor() {
    return new MainThreadExecutor();
  }
  
  // 得到默认的 CallAdapterFactories
  @Override List<? extends CallAdapter.Factory> defaultCallAdapterFactories(
      @Nullable Executor callbackExecutor) {
    if (callbackExecutor == null) throw new AssertionError();
    ExecutorCallAdapterFactory executorFactory = new ExecutorCallAdapterFactory(callbackExecutor);
    return Build.VERSION.SDK_INT >= 24
      ? asList(CompletableFutureCallAdapterFactory.INSTANCE, executorFactory)
      : singletonList(executorFactory);
  }
  
  // 得到默认的 ConverterFactories
  @Override List<? extends Converter.Factory> defaultConverterFactories() {
    return Build.VERSION.SDK_INT >= 24
        ? singletonList(OptionalConverterFactory.INSTANCE)
        : Collections.<Converter.Factory>emptyList();
  }
  
  // MainThreadExecutor 的作用就是切换回主线程,其具体的实现就是利用主线程的 Handler
  static class MainThreadExecutor implements Executor {
    private final Handler handler = new Handler(Looper.getMainLooper());
    @Override public void execute(Runnable r) {
      handler.post(r);
    }
  }
}

其中,又只有 Android 涉及到实际的 defaultCallbackExecutor,具体类型为 MainThreadExecutor,因为只有 Android 中有 UI 线程的概念,而 defaultCallbackExecutor 的作用就是为了切换线程,通过 execute() 方法,就可以切换了。

而其他的 defaultCallbackExecutornull

之后,对于 Retrofit.Builder#build() 的源码如下:

public Retrofit build() {
  // 1、必须要设置 baseUrl
  if (baseUrl == null) {
    throw new IllegalStateException("Base URL required.");
  }
  
  okhttp3.Call.Factory callFactory = this.callFactory;
  if (callFactory == null) {
  	 // 2、 callFactory 默认使用 okhttp 的 OkHttpClient
  	 // 或者使用 Builder#callFactory() 方法传递自定义的 
    callFactory = new OkHttpClient();
  }
  
  // 3、callbackExecutor 用来将回调传递到 UI 线程
  // 当然 platform.defaultCallbackExecutor() 默认为 null
  // 只有 Android 类型的 Platform 才会有一个实际的 MainThreadExecutor
  // 而 MainThreadExecutor 就是利用主线程的 handler 来实现将回调传递到 UI 线程
  Executor callbackExecutor = this.callbackExecutor;
  if (callbackExecutor == null) {
    callbackExecutor = platform.defaultCallbackExecutor();
  }
  
  // 4、adapterFactories 主要用于存储 CallAdapter.Factory,
  // 而 CallAdapter 是对原始的 OkHttpCall 实例进行转化用的
  // 如在使用 RxJavaCallAdapterFactory 的时候,就会得到 RxJavaCallAdapter,可以把 OkHttpCall 实例转换为 Observable
  // 或者默认的 CallAdapter,可以转换为 ExecutorCallbackCall,即通常在接口方法定义的返回值类型 retrofit2.Call<> (ExecutorCallbackCall 实现了 retrofit2.Call 接口 )
  // 实际上,与其是说转换,用包装更为准确,即将 OkHttpCall 包装为 Observable、ExecutorCallbackCall 等
  // (具体的原因第二部分的讲解)
  // 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));
  
  // 5、converterFactories 主要用于存储转化数据的对象
  // 如常用的 addConverterFactory(GsonConverterFactory.create())。
  // 而 Converter 的作用就是把 Call 转换为 Call
  // 注意,这里不是把 Call 中的 okhttp3.ResponseBody 转换为 R,因为 okhttp3.ResponseBody 也是经过转换来的;
  // 而是将 okhttp 请求中得到的原始的 okhttp3.ResponseBody 转换为目标 R 类型。
  // 只不过在 Android 的 Retrofit 中默认是将原始的 okhttp3.ResponseBody 实例转换为新的 okhttp3.ResponseBody 实例
  // 虽然类型没变,但还是经过了 Retrofit 的 Converter 的转换
  // (后面第二部分的第 4 点会说到)
  // 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.
  // 保证最开始的是 BuiltInConverters
  converterFactories.add(new BuiltInConverters()); 
  converterFactories.addAll(this.converterFactories);
  // 添加平台默认的 ConverterFactories 
  converterFactories.addAll(platform.defaultConverterFactories());

  // 通过设置的参数 new 出 Retrofit 实例
  return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
      unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
}

在上述源码中,主要涉及到几个点:

(1) 从注释 2 处可以知道,Retrofit 默认是借助 OkHttp 来实现网络请求的,而且实际上,也仅且用 OkHttp 来实现,因为 Retrofit.Builder 有且只存在两个成员方法,client(OkHttpClient client)RcallFactory(okhttp3.Call.Factory factory) 用来配置其成员变量 callFactory,而 okhttp3.Call.Factory 就是 okhttp3 用来生成 okhttp3.Call 的。

(2) 对于注释 4,涉及到了 CallAdapter,其作用就是为了把 Call 转换为 X,因为最原始的返回值就是 retrofit2.Call 类型的,如下:

@GET
fun test(): Call<ResponseBody>

// 使用了 RxJavaCallAdapterFactory 后,就可以转换为 Observable

(3) 对于注释 5,涉及到了 Converter,其作用了是为了把 Call 转换为指定类型 Call,如使用 GsonConverterFactory,就可以将 ResponseBody 转换为实体类。

在最后,就会通过配置的参数 new 出 Retrofit 实例。


2、retrofit.create(XXXService::class.java) 的作用

在通过 Retrofit.Builder 构建出 retrofit 实例之后,就会使用 retrofit.create(XXXService::class.java) 在方法来得到一个定义了方法的接口的实例。

如:


interface TestService {

    @GET(...)
    fun testMethod(): Call<ResponseBody>
}


val testService = retrofit.create(TestService::class.java)
val call = testService.testMethod()
call.enqueue(object : Callback<ResponseBody> {
    override fun onFailure(call: Call<ResponseBody>, t: Throwable) {}
    override fun onResponse(call: Call<ResponseBody>, response: Response<ResponseBody>) {}
})

Retrofit#create() 方法源码如下:

public <T> T create(final Class<T> service) {
  // 检查 service 是不是有效的,即必须是一个接口,且不能继承自其他接口
  Utils.validateServiceInterface(service);
  if (validateEagerly) {
    // 实现加载缓存 XXXService 中定义的方法
    eagerlyValidateMethods(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 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);
          }
          if (platform.isDefaultMethod(method)) {
            return platform.invokeDefaultMethod(method, service, proxy, args);
          }
          
          // 1
          return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
        }
      });
}

从源码中可以知道,create() 方法会返回关于 XXXService 的动态代理对象。以 TestService 为例,则通过 create() 方法(实际上是通过 Proxy.newProxyInstance() )来得到 TestService 的动态代理对象,通过该代理对象,就能够间接调用 TestService 中定义的方法。

当调用 TestServicetestMethod() 方法时,最终会调用 InvocationHandlerinvoke() 方法,该方法有 3 个参数,第一个是代理对象,第二个是调用的方法实例(即 testMethod() 方法实例),第三个是方法的参数。

正常情况下,是会执行到注释 1 处的。比如 testMethod(),该方法不是 Object 类的,也不是默认方法,因此会通过 Retrofit#loadServiceMethod() 方法得到一个对应的 ServiceMethod 对象实例,然后执行其 invoke() 方法并返回 testMethod() 方法定义的返回值类型的返回值,因为 fun testMethod(): Call,即返回一个 retrofit2.Call 类型的 call 实例。

简答的说,通过该代理对象,就实现了调用 TestService#testMethod() 方法,得到对应的返回值 call(retrofit2.Call 类型),然后就可实现同步或者异步请求了。

ServiceMethod<?> loadServiceMethod(Method method) {
  ServiceMethod<?> result = serviceMethodCache.get(method);
  if (result != null) return result;
  synchronized (serviceMethodCache) {
    result = serviceMethodCache.get(method);
    if (result == null) {
      // 解析 method 中的注解,生成对应的 ServiceMethod(实际上是 HttpServiceMethod,后面会说)
      result = ServiceMethod.parseAnnotations(this, method);
      serviceMethodCache.put(method, result);
    }
  }
  return result;
}

loadServiceMethod() 方法会根据传递进来的 method 实例,返回对应的 ServiceMethod 实例,如果还不存在,则会先通过 ServiceMethod.parseAnnotations 生产该实例,并缓存到 serviceMethodCacheConcurrentHashMap 类型)中,然后再返回。


3、ServiceMethod

在上面讲到,会通过 ServiceMethod.parseAnnotations() 方法得到 method 对应的 ServiceMethod 实例。实际上,ServiceMethod 是一个抽象类,真正的是 HttpServiceMethod 实例。

abstract class ServiceMethod<T> {
  static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
    // 1、解析 method 的注解(包括用于注释方法与参数的),得到对应的 requestFactory
    // requestFactory 用于创建 okhttp 需要的 request 请求
    RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);

	// 得到 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.");
    }

    // 2、根据传入的 requestFactory 得到对应的 HttpServiceMethod 实例
    return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
  }

  abstract T invoke(Object[] args);
}

从注释 2 可以知道,loadServiceMethod() 方法实际上得到的是 HttpServiceMethod 实例。

并且,在前面说到,通过代理对象来调用接口中定义的方法,实际上会调用 HttpServiceMethodinvoke() 方法。

loadServiceMethod(method).invoke(args != null ? args : emptyArgs);

invoke() 的源码如下:

@Override ReturnT invoke(Object[] args) {
  return callAdapter.adapt(
      new OkHttpCall<>(requestFactory, args, callFactory, responseConverter));
}

可以看到,在里面会利用 callAdapter 来将传入的 OkHttpCall 转换为 ReturnT 类型并返回,而 ReturnT 类型就是我们在接口 XXXService 中定义的方法的返回类型,如 retrofit2.Callrx.Observable 等。

至于 callAdapter 是怎么来的,后面会说。


4. RequestFactory.parseAnnotations(retrofit, method)

在上一点的注释 1 处,有提到要解析 method 的注释(就像下面的 @GET@Path 等),来生成一个 requestFactory 对象(来用于构建请求的 request)。

@GET(...)
fun testMethod(@Path("path1") path: String): Call<ResponseBody>

需要注意的是,是有两种注释,一种是用来修饰方法本身的,一种是用来修饰方法的参数的。

// RequestFactory.parseAnnotations()
static RequestFactory parseAnnotations(Retrofit retrofit, Method method) {
  return new Builder(retrofit, method).build();
}

因为注释有两种,因此实际上也是分两步来解析的。即下面源码中的注释 1、2。

// RequestFactory.Builder#build()
RequestFactory build() {
  // 1、解析注释方法的注解
  for (Annotation annotation : methodAnnotations) {
    parseMethodAnnotation(annotation);
  }
  ...
  int parameterCount = parameterAnnotationsArray.length;
  parameterHandlers = new ParameterHandler<?>[parameterCount];
  // 遍历所有参数
  for (int p = 0; p < parameterCount; p++) {
    // 2、解析用于注释参数的注解,进一步来说,是调用 parseParameterAnnotation() 方法,
    parameterHandlers[p] = parseParameter(p, parameterTypes[p], parameterAnnotationsArray[p]);
  }
  ...
  return new RequestFactory(this);
}

private ParameterHandler<?> parseParameter(
    int p, Type parameterType, @Nullable Annotation[] annotations) {
  ParameterHandler<?> result = null;
  if (annotations != null) {
    // 遍历所有注释参数的注解,得到对应的 ParameterHandler
    for (Annotation annotation : annotations) {
      ParameterHandler<?> annotationAction =
          parseParameterAnnotation(p, parameterType, annotations, annotation);
      ...
      result = annotationAction;
  }
  
  return result;
}

其中,ParameterHandler,即参数处理器,作用就是用来处理被不同注释注解的参数,具体的如下几种子类。分别针对参数进行处理成 request 中对应的内容,如 header 等。
Retrofit2.0 源码解析笔记_第1张图片


其实,讲到这里,对于 Retrofit2 的浅层次工作原理就大致说清楚了,即利用动态代理,以及运行时注解,来对接口中定义的方法进行处理。

下面还需要进一步探究一下,具体是怎么实现网络请求的,以及 CallAdapter、Converter 是怎样起作用的。


第二部分

1、HttpServiceMethod 实例化过程

前面说到,通过 HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory) 会得到 HttpServiceMethod 实例:

static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
    Retrofit retrofit, Method method, RequestFactory requestFactory) {
  // 1、根据 ReturnT 得到对应的 callAdapter
  CallAdapter<ResponseT, ReturnT> callAdapter = createCallAdapter(retrofit, method);
  //得到例如 Call 中原始的 ResponseBody 类型需要转换成的目标类型 R
  Type responseType = callAdapter.responseType();
  ...
  // 2、根据 ResponseT 得到对应的 responseConverter,即用于将 ResponseBody 转换为 ResponseT 的 converter
  Converter<ResponseBody, ResponseT> responseConverter =
      createResponseConverter(retrofit, method, responseType);
  // 3、callFactory 默认为 OkHttpClient
  // 在 Retrofit.Builder#build() 方法中设置的
  okhttp3.Call.Factory callFactory = retrofit.callFactory;
  // 4、最终返回 HttpServiceMethod 实例
  return new HttpServiceMethod<>(requestFactory, callFactory, callAdapter, responseConverter);
}

(1) 对于注释 1 处,有:

private static <ResponseT, ReturnT> CallAdapter<ResponseT, ReturnT> createCallAdapter(
    Retrofit retrofit, Method method) {
  // 得到方法的返回类型
  Type returnType = method.getGenericReturnType();
  // 得到注解方法的注释
  Annotation[] annotations = method.getAnnotations();
  try {
    //noinspection unchecked
    // 调用 retrofit.callAdapter() 得到目标 CallAdapter
    return (CallAdapter<ResponseT, ReturnT>) retrofit.callAdapter(returnType, annotations);
  } catch (RuntimeException e) { // Wide exception range because factories are user code.
    throw methodError(method, e, "Unable to create call adapter for %s", returnType);
  }
}

Retrofit#callAdapter() 最终会调用 Retrofit#nextCallAdapter()其中传递的参数 skipPastnull

public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType,
    Annotation[] annotations) {
  ...
  // 因为 skipPast == null,所以实际上会遍历整个 callAdapterFactories
  int start = callAdapterFactories.indexOf(skipPast) + 1;
  // 遍历 callAdapterFactories,然后调用每个 CallAdapter.Factory 元素的 get() 方法,
  // 看是否能够得到第一个正常的将 Call 转换为 returnType 类型的 CallAdapter
  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 完 callAdapterFactories 没有得到非空的 adapter,则会抛出异常
  ...
}

CallAdapter.Factory#get() 方法,会根据传入的 returnTypeannotations,如果符合条件,就会返回对应的 CallAdapter,否则,就会返回 null

例如,RxJavaCallAdapterFactory#get() 就会返回 RxJavaCallAdapter,其可以将 Call 转换为 Observable

(2) 对于注释 2 的 createResponseConverter() 方法,其实现与 createCallAdapter() 类似,最终也会调用 Retrofit#nextResponseBodyConverter()

public <T> Converter<ResponseBody, T> nextResponseBodyConverter(
    @Nullable Converter.Factory skipPast, Type type, Annotation[] annotations) {
  ...
  int start = converterFactories.indexOf(skipPast) + 1;
  for (int i = start, count = converterFactories.size(); i < count; i++) {
    Converter<ResponseBody, ?> converter =
        converterFactories.get(i).responseBodyConverter(type, annotations, this);
    if (converter != null) {
      //noinspection unchecked
      return (Converter<ResponseBody, T>) converter;
    }
  }
  // 如果遍历完 converterFactories 完也没有得到非空的 converter,那么也会报异常 
  ...
}

responseBodyConverter() 会根据目标类型,来看是否能得到对应的 Converter


2、CallAdapter 的调用

在第一部分的第 3 小点说过,当利用 Retrofit#create() 而生成的代理对象来调用在 XXXService 接口中定义的方法(如前面提到的 TestService 中的 testMothod() )时:

@GET()
fun testMethod(@Path("path1") path: String): Call<ResponseBody>

// HttpServiceMethod # invoke()
@Override ReturnT invoke(Object[] args) {
  return callAdapter.adapt(
      new OkHttpCall<>(requestFactory, args, callFactory, responseConverter));
}

实例上会调用该方法对应的 HttpServiceMethod 实例的 invoke(OkHttpCall) 方法,然后间接调用 HttpServiceMethod 实例中设置的 callAdapter.adapt() 来返回 testMothod() 方法定义的返回值类型的实例,这里即 Call 类型的 call 实例。

因为 testMethod() 方法返回值设置的是 Call 类型,为默认的类型,因此 callAdapter 实际上就是 Retrofit 设置的默认的 CallAdapter 实例(因为不需要人为添加其他的 CallAdapterFactory )。

还记得在 Refrofit.Builder#build() 中,会添加与平台相关的默认的 CallAdapterFactories

// 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));

在 Android 中即 Android (extends Platform)defaultCallAdapterFactories()

@Override List<? extends CallAdapter.Factory> defaultCallAdapterFactories(
    @Nullable Executor callbackExecutor) {
  if (callbackExecutor == null) throw new AssertionError();
  ExecutorCallAdapterFactory executorFactory = new ExecutorCallAdapterFactory(callbackExecutor);
  return Build.VERSION.SDK_INT >= 24
    ? asList(CompletableFutureCallAdapterFactory.INSTANCE, executorFactory)
    : singletonList(executorFactory);
}

当 SDK >= 24 时,默认有 CompletableFutureCallAdapterFactoryExecutorCallAdapterFactory

否则,就只有 ExecutorCallAdapterFactory

其中 CompletableFutureCallAdapterFactory 会得到 BodyCallAdapter 或者 ResponseCallAdapter 类型的 callAdapter

// CompletableFutureCallAdapterFactory # get()
@Override public @Nullable CallAdapter<?, ?> get(
    Type returnType, Annotation[] annotations, Retrofit retrofit) {
  if (getRawType(returnType) != CompletableFuture.class) {
    return null;
  }
  ...
  Type innerType = getParameterUpperBound(0, (ParameterizedType) returnType);
  if (getRawType(innerType) != Response.class) {
    // Generic type is not Response. Use it for body-only adapter.
    return new BodyCallAdapter<>(innerType);
  }
  ...
  Type responseType = getParameterUpperBound(0, (ParameterizedType) innerType);
  return new ResponseCallAdapter<>(responseType);
}

ExecutorCallAdapterFactory 会得到一个匿名的 CallAdapter 实例:

@Override public @Nullable CallAdapter<?, ?> get(
    Type returnType, Annotation[] annotations, Retrofit retrofit) {
  if (getRawType(returnType) != Call.class) {
    return null;
  }
  final Type responseType = Utils.getCallResponseType(returnType);
  return new CallAdapter<Object, Call<?>>() {
    @Override public Type responseType() {
      return responseType;
    }
    @Override public Call<Object> adapt(Call<Object> call) {
      return new ExecutorCallbackCall<>(callbackExecutor, call);
    }
  };
}

3、ExecutorCallAdapterFactory

针对接口方法设置的返回值为 retrofit2.Call 的情况。

// HttpServiceMethod # invoke()
@Override ReturnT invoke(Object[] args) {
  // callAdapter.adapt() 会 new 一个 OkHttpCall 实例传递给 ExecutorCallbackCall 的构造函数
  return callAdapter.adapt(new OkHttpCall<>(requestFactory, args, callFactory, responseConverter));
}

ExecutorCallAdapterFactory 举例,其对应的 HttpServiceMethod#invoke() 中的 callAdapter 就为 :

CallAdapter<Object, Call<?>>() {
  @Override public Type responseType() {
    return responseType;
  }
  @Override public Call<Object> adapt(Call<Object> call) {
    // (1)传递的第一个参数,即为 ExecutorCallbackCall#callbackExecutor 成员变量赋值,
    // 实际上是 Android(extends Platform) 中的 MainThreadExecutor。(第一部分有讲解)。
    // (2)传递的第二个参数,即为 ExecutorCallbackCall#delegate 成员变量赋值,且根据前面
    // 可知,实际为 OkHttpCall 类型的实例
    return new ExecutorCallbackCall<>(callbackExecutor, call);
  }
};

类型,一个匿名类实例,通过该匿名类实例的 adapt() 方法,就返回 ExecutorCallbackCall,以前面的实例代码为基础,假设有:

// interface TestService
@GET()
fun testMethod(@Path("path1") path: String): Call<ResponseBody>

// 示例代码
val testService = retrofit.create(TestService::class.java)
// 此时 call 的实际类型为 ExecutorCallbackCall
val call = testService.testMethod()

// 1
call.enqueue()
// 2
call.execute()

此时的 call 即为 ExecutorCallbackCall

// ExecutorCallAdapterFactory.ExecutorCallbackCall
static final class ExecutorCallbackCall<T> implements Call<T> {
  final Executor callbackExecutor;
  final Call<T> delegate;
  ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) {
    this.callbackExecutor = callbackExecutor;
    // 形参 delegate 即在调用构造方法时传递过来的,根据前面的内容,可以知道实际上
    // 为 OkHttpCall 
    this.delegate = delegate;
  }
  
  @Override public void enqueue(final Callback<T> callback) {
    // 利用 delegate 实现异步请求
    checkNotNull(callback, "callback == null");
    delegate.enqueue(new Callback<T>() {
      @Override public void onResponse(Call<T> call, final Response<T> response) {
        // 请求成功的话,利用 callbackExecutor 来且回主线程
        callbackExecutor.execute(new Runnable() {
          @Override public void run() {
            if (delegate.isCanceled()) {
              // Emulate OkHttp's behavior of throwing/delivering an IOException on cancellation.
              // 调用回调接口的 onFailure() 方法
              callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled"));
            } else {
              // 调用回调接口的 onResponse() 方法
              callback.onResponse(ExecutorCallbackCall.this, response);
            }
          }
        });
      }
      @Override public void onFailure(Call<T> call, final Throwable t) {
        callbackExecutor.execute(new Runnable() {
          @Override public void run() {
            // 调用回调接口的 onFailure() 方法
            callback.onFailure(ExecutorCallbackCall.this, t);
          }
        });
      }
    });
  }
  
  @Override public Response<T> execute() throws IOException {
    // 利用 delegate 实现同步请求
    return delegate.execute();
  }
  ...
}

当像示例代码那样调用 call.enqueue() 或者 call.execute() 时,则实际上是通过 delegate 来实现的,即通过 OkHttpCallenqueue()\execute() 来实现的。

4. OkHttpCall

final class OkHttpCall<T> implements Call<T> {
  private final RequestFactory requestFactory;
  private final Object[] args;
  private final okhttp3.Call.Factory callFactory;
  private final Converter<ResponseBody, T> responseConverter;
  private volatile boolean canceled;
  @GuardedBy("this")
  private @Nullable okhttp3.Call rawCall;
  @GuardedBy("this") // Either a RuntimeException, non-fatal Error, or IOException.
  private @Nullable Throwable creationFailure;
  @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;
  }

  // 异步请求方法
  @Override public void enqueue(final Callback<T> callback) {
    checkNotNull(callback, "callback == null");
    okhttp3.Call call;
    Throwable failure;
    synchronized (this) {
      // 如果 call 已经执行过,则抛出异常
      if (executed) throw new IllegalStateException("Already executed.");
      executed = true;
      call = rawCall;
      failure = creationFailure;
      if (call == null && failure == null) {
        try {
          // 得到真正的原始的 okhttp3.Call
          call = rawCall = createRawCall();
        } catch (Throwable t) {
          throwIfFatal(t);
          failure = creationFailure = t;
        }
      }
    }
    if (failure != null) {
      callback.onFailure(this, failure);
      return;
    }
    if (canceled) {
      call.cancel();
    }
    // 间接调用 call 的异步请求方法,且利用 okhttp3.Callback 间接实现回调
    call.enqueue(new okhttp3.Callback() {
      @Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
        Response<T> response;
        try {
          // 将原始的 rawResponse 解析为 retrofit2.Response
          response = parseResponse(rawResponse);
        } catch (Throwable e) {
          throwIfFatal(e);
          callFailure(e);
          return;
        }
        try {
          // 回调在 ExecutorCallbackCall#enqueue() 中通过 delegate.enqueue() 
          // 传递的 retrofit2.Call#onResponse()
          callback.onResponse(OkHttpCall.this, response);
        } catch (Throwable t) {
          t.printStackTrace();
        }
      }
      @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) {
          t.printStackTrace();
        }
      }
    });
  }

  // 通过 requestFactory,根据给接口方法传入的参数,创建原始的 okhttp3.Call
  private okhttp3.Call createRawCall() throws IOException {
    // 这里就用到了在 ServiceMethod.parseAnnotations() 中生成的 requestFactory
    // 而 callFactory 默认情况下则是 Retrofit.Budiler#build() 中设置的 OkHttpClient
    okhttp3.Call call = callFactory.newCall(requestFactory.create(args));
    if (call == null) {
      throw new NullPointerException("Call.Factory returned null.");
    }
    return call;
  }

  // 将关于 okhttp 最原始的 ResponseBody 转换为目标类型
  Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
    ResponseBody rawBody = rawResponse.body();

    // Remove the body's source (the only stateful object) so we can pass the response along.
    rawResponse = rawResponse.newBuilder()
        .body(new NoContentResponseBody(rawBody.contentType(), rawBody.contentLength()))
        .build();

    int code = rawResponse.code();
    if (code < 200 || code >= 300) {
      try {
        // Buffer the entire body to avoid future I/O.
        ResponseBody bufferedBody = Utils.buffer(rawBody);
        return Response.error(bufferedBody, rawResponse);
      } finally {
        rawBody.close();
      }
    }

    if (code == 204 || code == 205) {
      rawBody.close();
      return Response.success(null, rawResponse);
    }

    ExceptionCatchingResponseBody catchingBody = new ExceptionCatchingResponseBody(rawBody);
    try {
      // 利用 responseConverter 将最原始的 catchingBody 转换为目标类型
      // (1) 如果接口的方法定义的返回类型为 X
      // 则会将 catchingBody 转换为 okhttp3.ResponseBody
      // (2) 如果是利用 GsonConverterFactory 将解烦的方法返回类型定义 X
      // (ObjBean 为实体类),则 GsonResponseBodyConverter 会把 catchingBody
      // 转换为对应的实体类 ObjBean 对象
      T body = responseConverter.convert(catchingBody);
      // 然后将转换后的 body 填充到 retrofit2.Response 中,
      // 因为 parseResponse() 方法最终是返回 Response 类型的值
      // 其中 T 即 body 对应的类型,也就是接口的方法定义的返回类型 X 中的类型 T
      return Response.success(body, rawResponse);
    } catch (RuntimeException e) {
      // If the underlying source threw an exception, propagate that rather than indicating it was
      // a runtime exception.
      catchingBody.throwIfCaught();
      throw e;
    }
  }
}

通过 OkHttpCall 以及多重回调,最终实现了异步 Retrofit 的异步请求。

需要再次强调的是,此时请求的实现,是基于 CallAdapter 为 ExecutorCallAdapter 的情况。

5. BuiltInConverters

另外,在上面的 parseResponse() 方法中有提到 "将 catchingBody 转换为 okhttp3.ResponseBody"

此时是基于接口方法中定义的返回值为 X 来说的。

Retrofit.Builder#build() 中可知:

// Retrofit.Builder#build() 方法部分代码
converterFactories.add(new BuiltInConverters());
converterFactories.addAll(this.converterFactories);
converterFactories.addAll(platform.defaultConverterFactories());

会添加三类 ConverterFactory:
第一类是默认的 BuiltInConverters
第二类是在外部添加的;
第三类是与平台相关的默认的(对于 Android 来说,只有当 SDK >= 24 时,才会有一个 OptionalConverterFactory,否则为空)。

因此可以推断出,当 基于接口方法中定义的返回值为 X 来说,对应的 ConverterBuiltInConverters.responseBodyConverter()

@Override public @Nullable Converter<ResponseBody, ?> responseBodyConverter(
    Type type, Annotation[] annotations, Retrofit retrofit) {
  // 如果目标类型为 okhttp3.ResponseBody,则返回对应的 Converte
  if (type == ResponseBody.class) {
    // 如果方法被标注了 @Streaming,则返回 StreamingResponseBodyConverter;
    // 否则返回 BufferingResponseBodyConverter
    return Utils.isAnnotationPresent(annotations, Streaming.class)
        ? StreamingResponseBodyConverter.INSTANCE
        : BufferingResponseBodyConverter.INSTANCE;
  }
  if (type == Void.class) {
    return VoidResponseBodyConverter.INSTANCE;
  }
  if (checkForKotlinUnit) {
    try {
      if (type == Unit.class) {
        return UnitResponseBodyConverter.INSTANCE;
      }
    } catch (NoClassDefFoundError ignored) {
      checkForKotlinUnit = false;
    }
  }
  return null;
}

因此,从源码也印证了上面的推断,当设置的接口方法中的返回类型为 X 的时候,会使用 StreamingResponseBodyConverter/BufferingResponseBodyConverter

因为一般情况下,接口的方法不会使用 @Streaming,因此这里以 BufferingResponseBodyConverter 进行讲解。

// BuiltInConverters # BufferingResponseBodyConverter
static final class BufferingResponseBodyConverter
    implements Converter<ResponseBody, ResponseBody> {
  static final BufferingResponseBodyConverter INSTANCE = new BufferingResponseBodyConverter();
  
  @Override public ResponseBody convert(ResponseBody value) throws IOException {
    try {
      // Buffer the entire body to avoid future I/O.
      return Utils.buffer(value);
    } finally {
      value.close();
    }
  }
}

// Utils.buffer()
static ResponseBody buffer(final ResponseBody body) throws IOException {
  Buffer buffer = new Buffer();
  body.source().readAll(buffer);
  return ResponseBody.create(body.contentType(), body.contentLength(), buffer);
}

// ResponseBody.create()
public static ResponseBody create(final @Nullable MediaType contentType,
    final long contentLength, final BufferedSource content) {
  if (content == null) throw new NullPointerException("source == null");
  return new ResponseBody() {
    @Override public @Nullable MediaType contentType() {
      return contentType;
    }
    @Override public long contentLength() {
      return contentLength;
    }
    @Override public BufferedSource source() {
      return content;
    }
  };
}

通过 BufferingResponseBodyConverter#convert(),可以知道,其最终会根据传入的 valueOkHttpCall#parseResponse()里面说过,为 ExceptionCatchingResponseBody 实例),生成一个新的 ResponseBody 实例并返回。

其中,对于 OkHttpCall 来说,最原始的关于 okhttp 的 ResponseBody 其实是包装后的 ExceptionCatchingResponseBody


到这里,有关 Retrofit2.0 源码的梳理就基本结束了,当然这是在不涉及到额外设置的 CallAdapterFactoryConverterFactory,一切都是走默认设置的情况下来说明的。


最后,总结几个在源码分析中思考的问题,以便加深印象:

  1. Retrofit 的底层是怎么实现网络请求的?

    通过整篇文章的分析,就可以只是,是基于 OkHttp 来实现的。其实整个框架就是对 OkHttp 的再次封装。

  2. CallAdapter 的作用,是怎么把 OkHttpCall 转换为 X 的,以及转换的时机?

    (1) CallAdapter 的作用,就是得到接口中定义的方法的返回值类型对应的实例。

    比如方法的返回值对应的为 retrofit2.Call,则就有对应的 CallAdapterHttpServiceMethod#invoke() 中传入给 callAdapter.adapt(OkHttpCall) 方法的 OkHttpCall 实例给转换为 retrofit2.Call(实际上是 ExecutorCallbackCall,其实现了 retrofit2.Call),与其说是实现,其实说是包装更为准确,因为实际上还是要借助 OkHttpCall 来实现正在的网络请求。

    又如 RxJavaCallAdapter,则会将在 HttpServiceMethod#invoke() 中传入给 callAdapter.adapt(OkHttpCall) 方法的 OkHttpCall 实例包装成 rx.Observable

    其实我一开始在没有了解清楚的时候,以为 RxJavaCallAdapter 是会将原始的retrofit2.Call 转换为 rx.Observable,在反复阅读之后,才了解到 OkHttpCall 才是最原始的 Call 类型,通常情况下的 retrofit2.Call 中的 Call对应的其实是 ExecutorCallbackCall,即通常情况下的 retrofit2.Call 中的 Call 也是经过默认的 CallAdapter 转换来的。因此,如果前面中还有说 “ 将原始的retrofit2.Call 转换为 rx.Observable 则是笔误,因为我是写到这里才领悟到的,见谅。

    (2) 至于具体的转换,就得看具体的 CallAdapteradapt() 方法的源码了。以 RxJavaCallAdapter#adapt() 为例,最终会将传入的 call(即 OkHttpCall 实例)包装到 Observable 中。

    (3) 至于转换的时机,则是在调用 HttpServiceMethod#invoke() 时,即调用 XXXService 对应的代理对象中定义的方法的时候。

  3. Converter 的作用,以及是怎么把 ResponseBody 转换为 R 的?

    具体的说,Converter 实际上分为好多类型:

    (1) 用于将原始的 HTTP response body(即 OkHttpCall#parseResponse() 中的 catchingBody )转换为接口方法的返回类型 X 中的 R 类型的 Converter,名义上被命名为 ResponseBodyConverter。

    GsonConverterFactory 中的 GsonResponseBodyConverter,会将封装了原始的 okhttp3.ResponseBodycatchingBody 转换为具体的实体类。

    或者是默认的 Converter 将原始的关于 okhttp 的 catchingBody 直接转换为 ResponseBody

    前面的内容也可能存在笔误,因为在定义的接口的方法返回值中定义的 ResponseBody 也是经过转换来的,并不是最原始的。

    至于时机,则是在 OkHttpCall#parseResponse() 方法中调用 responseConverter.convert() 方法时。

    (2) 名义上被称为 RequestBodyConverter 的 Converter,用于将接口方法中的参数转换为 RequestBody,且是被 @Body、@Part、@PartMap 注解修饰的参数。

    比如 GsonConverterFactory 中的 GsonRequestBodyConverter,可以将被 @Body 修饰的实体类类型的参数转换为 Json 格式的 RequestBody。

    (3) 名义上被称为 StringConverter 的 Converter,用于将被 @Field、@FieldMap、@Header、@HeaderMap、@Path、@Query、@QueryMap 这几个注解修饰的参数转换为 String。

// Converter.Factory
abstract class Factory {
  /** 
   * Returns a {@link Converter} for converting an HTTP response body to {@code type}, or null if
   * {@code type} cannot be handled by this factory. This is used to create converters for
   * response types such as {@code SimpleResponse} from a {@code Call}
   * declaration.
   */
  public @Nullable Converter<ResponseBody, ?> responseBodyConverter(Type type,
      Annotation[] annotations, Retrofit retrofit) {
    return null;
  }
  /**
   * Returns a {@link Converter} for converting {@code type} to an HTTP request body, or null if
   * {@code type} cannot be handled by this factory. This is used to create converters for types
   * specified by {@link Body @Body}, {@link Part @Part}, and {@link PartMap @PartMap}
   * values.
   */
  public @Nullable Converter<?, RequestBody> requestBodyConverter(Type type,
      Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
    return null;
  }
  /**
   * Returns a {@link Converter} for converting {@code type} to a {@link String}, or null if
   * {@code type} cannot be handled by this factory. This is used to create converters for types
   * specified by {@link Field @Field}, {@link FieldMap @FieldMap} values,
   * {@link Header @Header}, {@link HeaderMap @HeaderMap}, {@link Path @Path},
   * {@ink Query @Query}, and {@link QueryMap @QueryMap} values.
   */
  public @Nullable Converter<?, String> stringConverter(Type type, Annotation[] annotations,
      Retrofit retrofit) {
    return null;
  }

  ...
}
  1. 对于多个 CallAdapter,在接口中定义的多个方法,能不能定义不同的返回类型?

    答案是能,可以实际尝试,比如,我可以同时为多个方法定义不同的返回值类型,如ObservableCallCall,都是能够正常运行的。(TranslationBean 为定义的一个实体类)

    原因在上文中的源码解析也可体现,因为针对不同的返回值类型,会在 callAdapterFactories 针对其获取对应的 CallAdapter

  2. 对于多种 Converter,能不能把关于 okhttp 原始的 ResponseBody 转换为多种类型?

    答案是能,由 4 可见,就同时存在 ResponseBodyTranslationBean 类型。同理,也会针对不用的目标类型在 converterFactories 找到对应的 Converter

  3. 在 Retrofit 中,是怎么生成一个 request 的?

    是通过 requestFactory 生成的。进一步来说是在解析了注解方法的注解之后,得到对应的 requestFactory 实例,然后在 OkHttpCall#createRawCall() 方法中,调用 requestFactory.create() 并出传入方法的参数来生成的对应的 request。

  4. 补充
    Retrofit2.0 源码解析笔记_第2张图片
    截图自:Android:这是一份全面 & 详细的Retrofit 2.0 源码分析指南

你可能感兴趣的:(读书笔记)