2025 再读Android Retrofit源码

147 阅读7分钟

Retrofit 源码流程解析

主要类介绍 (默认使用默认解析器DefaultCallAdapterFactory)

第一步 解析配置参数流程

  • Retrofit
  • ServiceMethod --> parseAnnotations(retrofit, method)
  • RequestFactory --> parseAnnotations(retrofit, method)
  • HttpServiceMethod --> parseAnnotations(retrofit, method, requestFactory) (返回一个CallAdapter对象,核心方法)
  • HttpServiceMethod的内部类类CallAdapted(requestFactory, callFactory, responseConverter, callAdapter) 参数callAdapter来自于retrofit的CallAdapter
  • ServiceMethod.invoke(args)
  • HttpServiceMethod.invoke(args)
  • OkHttpCall 包装了okhtt3 的Call的具体使用, 提供了enqueue/execute 方法执行网络请求
  • HttpServiceMethod.CallAdapted --> adapt(call, args) --> retrofit.CallAdapted.adapt(call)
  • DefaultCallAdapterFactory
    // --> get() --> adapt(Call<Object> call)
    get() --> 匿名实现了Call<Object> adapt(Call<Object> call) 方法; CallAdapter.adapt() 的作用是 将 Retrofit 的原始 Call 适配成你需要的调用形式。默认情况下它什么也不做,但通过自定义 CallAdapter(如 RxJava、Coroutines),可以支持更丰富的异步编程范式。
    

第二步 请求发起调用流程

调用 enqueue() 或 execute() 当用户拿到返回的 Call 对象后,手动调用 enqueue() 或 execute() 时,会直接触发 OkHttpCall 的对应方法:

// 用户代码示例
Call<Response> call = apiService.getData();
call.enqueue(callback); // 或 call.execute();
  • OkHttpCall OkHttpCall 是 Retrofit 对 OkHttp 的封装,其核心逻辑如下:

同步请求 execute()

// OkHttpCall.java
@Override public Response<T> execute() throws IOException {
    okhttp3.Call call;
    synchronized (this) {
        // 1. 创建或复用 OkHttp 的 Call 对象
        call = createRawCall();
    }
    // 2. 执行同步请求,并解析响应
    return parseResponse(call.execute());
}

异步请求 enqueue()

// OkHttpCall.java
@Override public void enqueue(Callback<T> callback) {
    okhttp3.Call call;
    synchronized (this) {
        // 1. 创建或复用 OkHttp 的 Call 对象
        call = createRawCall();
    }
    // 2. 执行异步请求
    call.enqueue(new okhttp3.Callback() {
        @Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
            // 3. 解析响应并回调
            Response<T> response = parseResponse(rawResponse);
            callback.onResponse(OkHttpCall.this, response);
        }
        @Override public void onFailure(okhttp3.Call call, IOException e) {
            callback.onFailure(OkHttpCall.this, e);
        }
    });
}

最终执行到 OkHttp

核心逻辑如下:

OkHttpCall 内部通过 createRawCall() 创建 OkHttp 的 okhttp3.Call 对象,并委托给它执行请求: RequestFactorycreate方法中 主要是将解析后的method和参数列表封装到Invocation中,并将Invocation存储到Okhttp的Reequest的tag属性中,tag是一个HashMap集合; 并最终返回Okhttp的Request对象。

// OkHttpCall.java
private okhttp3.Call createRawCall() throws IOException {
    okhttp3.Call call = callFactory.newCall(requestFactory.create(args));
    if (call == null) {
      throw new NullPointerException("Call.Factory returned null.");
    }
    return call;
  }

// RequestFactory.java
okhttp3.Request create(Object[] args) throws IOException {
    ...
    return requestBuilder.get().tag(Invocation.class, new Invocation(method, argumentList)).build();
    }
流程总结
  1. 动态代理拦截 → 生成 ServiceMethod 和 OkHttpCall。

  2. CallAdapter.adapt() → 默认直接返回 OkHttpCall。

  3. 用户调用 enqueue()/execute() → 触发 OkHttpCall 的对应方法。

  4. OkHttpCall 委托给 OkHttp → 通过 okhttp3.Call 发起实际网络请求。


Retrofit 源码流程跟踪详解

  1. Retrofit初始化入口
 public <T> T getApiService(Class<T> serviceClass) {
        return new Retrofit.Builder().baseUrl(url)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava3CallAdapterFactory.create())
                // 创建okhttpclient
                .client(mOkhttpClient)
                .build()
                // 通过动态代理创建api
                .create(serviceClass);
    }
  1. 调用Retrofit的create方法,传入接口的class对象,创建接口的实现类。
public <T> T create(final Class<T> service) {
    validateServiceInterface(service);
    return (T)
    // 创建动态代理
        Proxy.newProxyInstance(
            service.getClassLoader(),
            new Class<?>[] {service},
            new InvocationHandler() {
              private final Platform platform = Platform.get();
              private final Object[] emptyArgs = new Object[0];

              @Override
              public @Nullable Object invoke(Object proxy, Method method, @Nullable Object[] args)
                  throws Throwable {
                // If the method is a method from Object then defer to normal invocation.
                if (method.getDeclaringClass() == Object.class) {
                  return method.invoke(this, args);
                }
                args = args != null ? args : emptyArgs;
                return platform.isDefaultMethod(method)
                    ? platform.invokeDefaultMethod(method, service, proxy, args)
                    : loadServiceMethod(method).invoke(args);
              }
            });
  }

使用 Proxy.newProxyInstance() 创建代理实例,需要三个参数: (被代理队形是传入的参数 service)

  • 类加载器: service.getClassLoader()

  • 要代理的接口数组: new Class<?>[] {service}

  • 调用处理器: 自定义的 InvocationHandler 实现


  1. 具体方法片段代码解析
return platform.isDefaultMethod(method)
    ? platform.invokeDefaultMethod(method, service, proxy, args)
    : loadServiceMethod(method).invoke(args);

这段代码是 Retrofit 动态代理中处理接口方法调用的核心分支逻辑,主要区分和处理两种类型的接口方法:

1. Java 8 默认方法 (Default Method)

判断条件platform.isDefaultMethod(method)

  • 什么是默认方法:Java 8 引入的特性,允许接口中包含带有实现的方法(使用 default 关键字)

    public interface MyApi {
        @GET("users")
        Call<List<User>> getUsers();
        
        // 默认方法
        default String getDefaultName() {
            return "default_name";
        }
    }
    
  • 为什么需要特殊处理:因为这些方法已经有实现,不应该被 Retrofit 转换为 HTTP 请求

  • 处理方式platform.invokeDefaultMethod(method, service, proxy, args)

    • 直接调用接口中的默认方法实现
    • 保持默认方法的原有行为不变

2. 普通抽象方法 (常规 Retrofit 接口方法)

判断条件:非默认方法的情况

  • 典型特征:带有 Retrofit 注解(如 @GET, @POST 等)的抽象方法

    @GET("users/{id}")
    Call<User> getUser(@Path("id") String userId);
    
  • 处理方式loadServiceMethod(method).invoke(args)

    • loadServiceMethod(method):加载或创建方法对应的 ServiceMethod
      • 解析方法注解(HTTP 方法、路径、参数等)
      • 创建适当的调用适配器(如 Call 类型)
      • 缓存解析结果以提高性能
    • .invoke(args):使用解析后的配置执行实际调用
      • 构建 HTTP 请求
      • 处理参数
      • 返回适当的响应类型

设计意义

这种分支处理使得 Retrofit 能够:

  1. 保持与 Java 8+ 的兼容性:正确处理接口中的默认方法
  2. 明确区分:哪些方法应该被转换为 HTTP 请求,哪些应该保持原样
  3. 灵活扩展:通过 Platform 类抽象不同平台(Android、Java 8 等)的特殊处理

实际执行流程示例

对于以下接口:

public interface GitHubService {
    // 普通抽象方法 - 会被转换为HTTP请求
    @GET("users/{user}/repos")
    Call<List<Repo>> listRepos(@Path("user") String user);
    
    // 默认方法 - 直接调用实现
    default String defaultEndpoint() {
        return "https://api.github.com";
    }
}
  • 调用 listRepos("octocat") → 走 loadServiceMethod 分支,转换为 HTTP 请求
  • 调用 defaultEndpoint() → 走 invokeDefaultMethod 分支,直接返回 "api.github.com"

DefaultCallAdapterFactory解析器源码

package retrofit2;

import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Objects;
import java.util.concurrent.Executor;
import javax.annotation.Nullable;
import okhttp3.Request;
import okio.Timeout;

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

    final Executor executor =
        Utils.isAnnotationPresent(annotations, SkipCallbackExecutor.class)
            ? null
            : callbackExecutor;

    return new CallAdapter<Object, Call<?>>() {
      @Override
      public Type responseType() {
        return responseType;
      }

      @Override
      public Call<Object> adapt(Call<Object> call) {
        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()) {
                      // 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();
    }
  }
}

DefaultCallAdapterFactory 的源码中,没有直接看到 T adapt(Call<R> call) 方法的独立定义,这是因为 Retrofit 的 CallAdapter 接口使用了 泛型类型参数,而 DefaultCallAdapterFactory 通过 匿名内部类 的方式实现了 CallAdapter 接口,并将泛型具体化为 Call<?>。下面我会详细解释:


1. CallAdapter 接口的定义

首先回顾 CallAdapter 接口的原始定义(来自 Retrofit 源码):

public interface CallAdapter<R, T> {
  Type responseType();
  T adapt(Call<R> call);  // 关键方法!
}
  • R:原始响应类型(如 Response<User>)。
  • T:适配后的返回类型(如 Call<User>Observable<User> 等)。

2. DefaultCallAdapterFactory 的实现

DefaultCallAdapterFactory 中,get() 方法返回了一个 匿名内部类CallAdapter 实例:

return new CallAdapter<Object, Call<?>>() {  // 注意泛型参数:R=Object, T=Call<?>
  @Override
  public Type responseType() {
    return responseType;
  }

  @Override
  public Call<Object> adapt(Call<Object> call) {  // 这就是 T adapt(Call<R> call) 的实现!
    return executor == null ? call : new ExecutorCallbackCall<>(executor, call);
  }
};
  • 泛型具体化:这里明确指定了 R=ObjectT=Call<?>,因此 adapt() 方法的签名变为 Call<Object> adapt(Call<Object> call)
  • 方法逻辑
    • 如果 executornull,直接返回原始 call(即 OkHttpCall)。
    • 如果 executor 存在,返回包装后的 ExecutorCallbackCall(用于切换回调线程)。

3. 为什么看起来不像 T adapt(Call<R> call)

由于 Java 的泛型擦除和匿名内部类的语法,adapt() 的具体实现被“隐藏”在匿名类中。但本质上:

  • Call<Object> adapt(Call<Object> call) 就是 T adapt(Call<R> call) 的具体实现。
  • 因为 T 被具体化为 Call<?>R 被具体化为 Object,所以方法签名看起来不同,但逻辑完全一致。

4. 关键点:adapt() 的作用

在这个实现中,adapt() 方法的主要职责是:

  1. 线程切换:通过 ExecutorCallbackCall 将回调切换到指定的 Executor(如主线程的 HandlerExecutor)。
  2. 透明传递:如果不需要线程切换(executor == null),直接返回原始 Call 对象。

5. 执行流程示例

假设用户定义了一个接口方法:

@GET("/user")
Call<User> getUser();

Retrofit 的处理步骤如下:

  1. 动态代理调用 invoke()
    • 创建 OkHttpCall(原始 Call 对象)。
  2. 调用 adapt()
    • 如果未设置 executor,直接返回 OkHttpCall
    • 如果设置了 executor,返回 ExecutorCallbackCall(包装 OkHttpCall)。
  3. 用户调用 enqueue()
    • 如果是 ExecutorCallbackCall,会通过 executor 切换线程后,再调用 OkHttpCall.enqueue()

6. 总结
  • adapt() 的存在:确实实现了,只是以匿名内部类的方式呈现,且泛型被具体化。
  • 核心逻辑:决定是否包装 Call 对象以实现线程切换。
  • 默认行为:如果没有设置 callbackExecutoradapt() 直接返回原始 Call,此时 enqueue()/execute() 会直接触发 OkHttpCall 的请求。

通过这种设计,Retrofit 保持了默认行为的简洁性,同时允许灵活扩展(如 RxJava 的 CallAdapter)。

目前作者在魔都求职中, 希望被各位大佬推荐 1299891195@qq.com, 谢谢