This page looks best with JavaScript enabled

Retrofit Source Code

 ·  ☕ 4 min read

Retrofit

官话: A type-safe HTTP client for Android and Java

我的理解: 它提供了一种方便的 HTTP 请求编写方式. 它通过解析接口方法的注解, 构造出对应的 HTTP 请求方法, 并且支持添加自己的 CallAdapter 和 Converter 定制化请求的创建和结果的解析.

定义 HTTP 接口方法

1
2
3
4
public interface GitHubService {
  @GET("users/{user}/repos")
  Call<List<Repo>> listRepos(@Path("user") String user);
}

创建 Retrofit 实例和请求方法

1
2
3
4
5
Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("https://api.github.com/")
    .build();

GitHubService service = retrofit.create(GitHubService.class);

发出请求并获取结果

1
Call<List<Repo>> repos = service.listRepos("octocat");

下图是以 Rxjava2CallAdapter 为 CallAdapter 时, 在 create 之后, 调用方法的大致流程:

Retrofit流程

Retrofit 的构造

  • 在多处使用了建造者模式, 工厂模式
  • 在接口的实现处使用了动态代理

Retrofit.Builder

一些配置参数:

属性 类型 说明
platform Platform 代码运行的平台, Retrofit 提供两个默认的 Andorid 和 Java
callFactory okhttp3.Call.Factory 请求的构造器
baseUrl HttpUrl 所有请求的BaseUrl
converterFactories List<Converter.Factory> 结果的转化器集
callAdapterFactories List<CallAdapter.Factory> 请求的适配器转化集
callbackExecutor Executor Java的Executor,结果回调执行的线程池
validateEagerly boolean 是否提前验证的标志

通过 Builder 构造 Retrofit 实例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public Retrofit build() {

  // 请求构造器,默认为 OkHttpClient
  okhttp3.Call.Factory callFactory = this.callFactory;
  if (callFactory == null) {
    callFactory = new OkHttpClient();
  }

  // 回调执行的线程池,默认为平台默认的,在 Android 上为 MainExecutor
  Executor callbackExecutor = this.callbackExecutor;
  if (callbackExecutor == null) {
    callbackExecutor = platform.defaultCallbackExecutor();
  }

  // 添加默认的 callAdapterFactor
  List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
  callAdapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));

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

  // 添加自带的转换器,确保能转化所有类型
  converterFactories.add(new BuiltInConverters());
  converterFactories.addAll(this.converterFactories);
  
  // 构造 Retrofit 实例
  return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
      unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
}

创建 Retrofit 实例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public <T> T create(final Class<T> service) {
  // 验证传入的参数是否是一个没有继承其他接口的接口
  Utils.validateServiceInterface(service);
  // 如果设置了提前验证,会在 create 时就构造 serviceMethod,加入缓存.,
  if (validateEagerly) {
    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.
            // 比如 toString, hashCode, equal 等方法会直接反射调用
            if (method.getDeclaringClass() == Object.class) {
              return method.invoke(this, args);
            }
            // 如果是平台自有的方法,则通过平台调用
            if (platform.isDefaultMethod(method)) {
              return platform.invokeDefaultMethod(method, service, proxy, args);
            }
            // 构造一个 serviceMethod 来执行真正的操作
            return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
          }
      }
    );
}

可以看出创建过程就是为我们定义的接口创建代理对象,当调用方法时通过代理对象去执行真正的操作.

ServiceMethod

在调用 Retrofit 的 create 最后,会调用 loadServiceMethod 返回 ServiceMethod 实例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
ServiceMethod<?> loadServiceMethod(Method method) {
  ServiceMethod<?> result = serviceMethodCache.get(method);
  if (result != null) return result;

  synchronized (serviceMethodCache) {
    result = serviceMethodCache.get(method);
    if (result == null) {
      // 通过 parseAnnotations 静态方法获得实例
      result = ServiceMethod.parseAnnotations(this, method);
      serviceMethodCache.put(method, result);
    }
  }
  return result;
}

parseAnnotations

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
  // RequestFactory 里储存了请求相关的参数, HTTP Method, headers, contentType 等
  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);
  }
  // 返回值不能是 void,如需要可以使用 void 的包装类 Void
  if (returnType == void.class) {
    throw methodError(method, "Service methods cannot return void.");
  }
  // 返回 HtppServiceMethod
  return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
}

HttpServiceMethod

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
    Retrofit retrofit, Method method, RequestFactory requestFactory) {
  // 创建 CallAdapter
  CallAdapter<ResponseT, ReturnT> callAdapter = createCallAdapter(retrofit, method);
  Type responseType = callAdapter.responseType();
  if (responseType == Response.class || responseType == okhttp3.Response.class) {
    throw methodError(method, "'"
        + Utils.getRawType(responseType).getName()
        + "' is not a valid response body type. Did you mean ResponseBody?");
  }
  // HEAD 请求的返回值必须是 Void 类型
  if (requestFactory.httpMethod.equals("HEAD") && !Void.class.equals(responseType)) {
    throw methodError(method, "HEAD method must use Void as response type.");
  }
  // 创建 ResponseConverter
  Converter<ResponseBody, ResponseT> responseConverter =
      createResponseConverter(retrofit, method, responseType);

  okhttp3.Call.Factory callFactory = retrofit.callFactory;
  return new HttpServiceMethod<>(requestFactory, callFactory, callAdapter, responseConverter);
}

最终执行请求时,会走到 serviceMethod 的 invoke 处:

1
2
3
4
5
6
@Override ReturnT invoke(Object[] args) {
  // 这里的 callAdapter 是从 Retrofit 的 callAdapterFactories 中找到匹配请求方法返回值的 callAdapter
  // 不单独 addCallAdapterFactory 话,默认就是 platform 提供的
  return callAdapter.adapt(
      new OkHttpCall<>(requestFactory, args, callFactory, responseConverter));
}

至此, Retrofit 就将 interface 定义的接口方法通过动态代理,转换成了匹配 interface 方法返回值的 CallAdapter.

RxJava2CallAdapterFactory

常用的 RxJava2CallAdapterFactory, 会匹配返回值是 Observable, Single, Flowable Maybe.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
  Class<?> rawType = getRawType(returnType);
  if (rawType == Completable.class) {
    return new RxJava2CallAdapter(Void.class, scheduler, isAsync, false, true, false, false, false, true);
  }
  boolean isFlowable = rawType == Flowable.class;
  boolean isSingle = rawType == Single.class;
  boolean isMaybe = rawType == Maybe.class;
  if (rawType != Observable.class && !isFlowable && !isSingle && !isMaybe) {
    return null;
  }
  boolean isResult = false;
  boolean isBody = false;
  Type responseType;
  ...
  Type observableType = getParameterUpperBound(0, (ParameterizedType) returnType);
  Class<?> rawObservableType = getRawType(observableType);
  if (rawObservableType == Response.class) {
    ...
    responseType = getParameterUpperBound(0, (ParameterizedType) observableType);
  } else if (rawObservableType == Result.class) {
    ...
    responseType = getParameterUpperBound(0, (ParameterizedType) observableType);
    isResult = true;
  } else {
    responseType = observableType;
    isBody = true;
  }
  return new RxJava2CallAdapter(responseType, scheduler, isAsync, isResult, isBody, isFlowable, isSingle, isMaybe, false);
}

接口的 Proxy invoke 时会调到 adapt 方法,返回声明的返回值. RxJava2Adapter 这里可以返回几种 Observeable. 当对这些 Observable 进行 subscribe时, 会走到 CallExecuteObservableCallEnqueueObservableonSubscribeActual 方法.

  • CallEnqueueObservable 里会调用 OkHttpCall 的 enqueue 异步发起请求
  • CallExecuteObservable 里会调用 OkHttpCall 的 execute 同步发起请求
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
@Override public Object adapt(Call<R> call) {
  Observable<Response<R>> responseObservable = isAsync
      ? new CallEnqueueObservable<>(call)
      : new CallExecuteObservable<>(call);

  Observable<?> observable;
  if (isResult) {
    observable = new ResultObservable<>(responseObservable);
  } else if (isBody) {
    observable = new BodyObservable<>(responseObservable);
  } else {
    observable = responseObservable;
  }

  if (scheduler != null) {
    observable = observable.subscribeOn(scheduler);
  }

  if (isFlowable) {
    return observable.toFlowable(BackpressureStrategy.LATEST);
  }
  if (isSingle) {
    return observable.singleOrError();
  }
  if (isMaybe) {
    return observable.singleElement();
  }
  if (isCompletable) {
    return observable.ignoreElements();
  }
  return observable;
}
Support the author with
alipay QR Code
wechat QR Code

Yang
WRITTEN BY
Yang
Developer