Retrofit 全面解析

A type-safe HTTP client for Android and Java

源码分析版本:
implementation 'com.squareup.retrofit2:retrofit:2.9.0'

Retrofit的使用

关于Retrofit的使用,这里就不再多于的讲解了,相信只要是做Android开发的都会使用Retrofit
https://square.github.io/retrofit/
最简单的使用方式如下:

  1. interface GitHubService {
  2. @GET("users/{user}/repos")
  3. fun listRepos(@Path("user") user:String?):Call<List<Repo>>
  4. }
  5. val retrofit = Retrofit.Builder()
  6. .baseUrl("https://api.github.com/")
  7. .addConverterFactory(GsonConverterFactory.create()) //gson的转换工厂
  8. .build()
  9. retrofit.create(GitHubService::class.java).listRepos("octocat")
  10. .enqueue(object :Callback<List<Repo>>{
  11. override fun onResponse(call: Call<List<Repo>>, response: Response<List<Repo>>) {
  12. println(response.body()?.size)
  13. }
  14. override fun onFailure(call: Call<List<Repo>>, t: Throwable) {
  15. TODO("Not yet implemented")
  16. }
  17. })

看源码的思路,专注于一条线路,直到看懂这条线路。

下面我们先专注于create方法这条路线A,然后是enqueue这条路线B.
image.png

从Create方法分析

下面这段代码,通过Builder模式构建Retrofit实例

  1. val retrofit = Retrofit.Builder()
  2. .baseUrl("https://api.github.com/")
  3. .addConverterFactory(GsonConverterFactory.create()) //gson的转换工厂
  4. .build()

retrofit.create() 方法进行初始化代码如下:
通过Java的动态代理方式,对传递过来的Class代理方法,注意Class必须是接口,Java中的动态代理只能代理接口。
我们首先看第一步validateServiceInterface方法干了什么?

  1. public <T> T create(final Class<T> service) {
  2. //1. 进行初始化验证service接口 先看一下这个方法
  3. validateServiceInterface(service);
  4. //2. 返回代理对象
  5. return (T)
  6. //使用java提供的动态代理
  7. Proxy.newProxyInstance(
  8. service.getClassLoader(),
  9. new Class<?>[] {service},
  10. new InvocationHandler() {
  11. private final Platform platform = Platform.get();
  12. private final Object[] emptyArgs = new Object[0];
  13. @Override
  14. public @Nullable Object invoke(Object proxy, Method method, @Nullable Object[] args)
  15. throws Throwable {
  16. // If the method is a method from Object then defer to normal invocation.
  17. if (method.getDeclaringClass() == Object.class) {
  18. return method.invoke(this, args);
  19. }
  20. args = args != null ? args : emptyArgs;
  21. return platform.isDefaultMethod(method)
  22. ? platform.invokeDefaultMethod(method, service, proxy, args)
  23. : loadServiceMethod(method).invoke(args);
  24. }
  25. });
  26. }

validateServiceInterface 主要作用初始化的时候进行验证,验证service class是否使用正确:

  1. private void validateServiceInterface(Class<?> service) {
  2. //这个class必须是一个接口,如果不是接口就会报错
  3. if (!service.isInterface()) {
  4. throw new IllegalArgumentException("API declarations must be interfaces.");
  5. }
  6. //将接口加入到队列中
  7. Deque<Class<?>> check = new ArrayDeque<>(1);
  8. check.add(service);
  9. while (!check.isEmpty()) {
  10. //从队列中取出接口类
  11. Class<?> candidate = check.removeFirst();
  12. //class 接口类 不能有泛型 如:GithubService<T> 会报错
  13. if (candidate.getTypeParameters().length != 0) {
  14. StringBuilder message =
  15. new StringBuilder("Type parameters are unsupported on ").append(candidate.getName());
  16. if (candidate != service) {
  17. message.append(" which is an interface of ").append(service.getName());
  18. }
  19. throw new IllegalArgumentException(message.toString());
  20. }
  21. //判断接口 是否还有继承 如果有继续循环
  22. Collections.addAll(check, candidate.getInterfaces());
  23. }
  24. // 开关,validateEagerly 开发和正式 能够快速验证
  25. if (validateEagerly) {
  26. Platform platform = Platform.get();
  27. for (Method method : service.getDeclaredMethods()) {
  28. //过滤接口的默认方法和静态方法
  29. if (!platform.isDefaultMethod(method) && !Modifier.isStatic(method.getModifiers())) {
  30. //验证和加载接口类的方法
  31. loadServiceMethod(method);
  32. }
  33. }
  34. }
  35. }

其实validateEagerly 主要用来在初始化的时候进行验证接口中的所有方法配置,一般在开发阶段进行设置为true,Retrofit给出的解释如下:

  1. /**
  2. * When calling {@link #create} on the resulting {@link Retrofit} instance, eagerly validate the
  3. * configuration of all methods in the supplied interface.
  4. 当在结果{@link Retrofit}实例上调用{@link #create}时,急切地验证提供的接口中所有方法的配置。
  5. */
  6. public Builder validateEagerly(boolean validateEagerly) {
  7. this.validateEagerly = validateEagerly;
  8. return this;
  9. }

在初始化验证通过之后,会通过Java中的动态代理模式,生成代理对象。

动态代理

Java中的动态代理,通过Proxy生成接口的代理对象,当调用代理对象的方法的时候就会调用invoke方法。这也是Retrofit的核心的入口。

  1. return (T)
  2. //使用java提供的动态代理
  3. Proxy.newProxyInstance(
  4. service.getClassLoader(),
  5. new Class<?>[] {service},
  6. new InvocationHandler() {
  7. private final Platform platform = Platform.get();
  8. private final Object[] emptyArgs = new Object[0];
  9. @Override
  10. public @Nullable Object invoke(Object proxy, Method method, @Nullable Object[] args)
  11. throws Throwable {
  12. // If the method is a method from Object then defer to normal invocation.
  13. // 如果方式是在Object类中的方法,直接调用
  14. if (method.getDeclaringClass() == Object.class) {
  15. return method.invoke(this, args);
  16. }
  17. args = args != null ? args : emptyArgs;
  18. //platform 做兼容处理
  19. return platform.isDefaultMethod(method) //考虑java8的兼容问题
  20. //如果是默认方法 直接调用默认方法
  21. ? platform.invokeDefaultMethod(method, service, proxy, args)
  22. : loadServiceMethod(method).invoke(args);//代理接口的方法
  23. }
  24. });

其实动态代理的原理非常简单,实际上等价于下面的代码:主要去关注invoke回调方法中

  1. class ProxyGitHubService : GitHubService {
  2. val invocationHandler:InvocationHandler = InvocationHandler(object : (Any, Method, Array<Any>) -> Any{
  3. override fun invoke(p1: Any, p2: Method, p3: Array<Any>): Any {
  4. // If the method is a method from Object then defer to normal invocation.
  5. if (method.getDeclaringClass() == Object.class) {
  6. return method.invoke(this, args);
  7. }
  8. args = args != null ? args : emptyArgs;
  9. return platform.isDefaultMethod(method)
  10. ? platform.invokeDefaultMethod(method, service, proxy, args)
  11. : loadServiceMethod(method).invoke(args);
  12. }
  13. })
  14. override fun listRepos(user: String?): Call<List<Repo>> {
  15. val method = GitHubService::class.java.getDeclaredMethod("listRepos",String::class.java)
  16. return invocationHandler.invoke(this,method,user)
  17. }
  18. }

最终核心的方法就是loadServiceMethod方法,最终调用了invoke()方法。下面来看loadServiceMethod做了什么?

loadServiceMethod

loadServiceMethod代码如下:从Map集合获取ServiceMethod 并返回,Retrifit做了缓存处理,下一次在调用直接从缓存中获取。这么这个ServiceMethod类有什么作用呢?

  1. ServiceMethod<?> loadServiceMethod(Method method) {
  2. //获取缓存的取出来,serviceMethodCache就是一个Map集合
  3. ServiceMethod<?> result = serviceMethodCache.get(method);
  4. //如果存在的话则直接返回
  5. if (result != null) return result;
  6. synchronized (serviceMethodCache) {
  7. result = serviceMethodCache.get(method);
  8. //如果没有则存入缓存
  9. if (result == null) {
  10. //处理接口方法
  11. result = ServiceMethod.parseAnnotations(this, method);
  12. serviceMethodCache.put(method, result);
  13. }
  14. }
  15. return result;
  16. }

下面我们来看ServiceMethod类,是一个抽象类,invoke方法并没有实现,可以看到通过parseAnnotations方法返回了ServiceMethod类的实例对象,我们找到ServiceMethod的实现类HttpServiceMethod类。
这里我们先把关注点放到invoke方法上,

  1. abstract class ServiceMethod<T> {
  2. static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
  3. // 解析方法的注解,返回值类型,传递的参数
  4. RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);
  5. //获取方法的返回值类型
  6. Type returnType = method.getGenericReturnType();
  7. if (Utils.hasUnresolvableType(returnType)) {
  8. throw methodError(
  9. method,
  10. "Method return type must not include a type variable or wildcard: %s",
  11. returnType);
  12. }
  13. if (returnType == void.class) {
  14. throw methodError(method, "Service methods cannot return void.");
  15. }
  16. return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
  17. }
  18. abstract @Nullable T invoke(Object[] args);
  19. }

HttpServiceMethod

我们先看invoke方法的实现:

  1. @Override
  2. final @Nullable ReturnT invoke(Object[] args) {
  3. Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
  4. return adapt(call, args);
  5. }

从invoke方法中可以看到有两条线路:OkHttpCall以及adapt. 通过源码线路分析图如下,这两条线路我们先看OkHttpCall这条线路C。
image.png

线路C -> OkHttpCall

可以看到OkHttpCall实现了Call接口,Call接口是否很熟悉,在我们使用Retrofit的使用,接口的方法会返回一个call

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

那也就是说,OkHttpCall实现了enqueue()方法。代码如下:

  1. @Override
  2. public void enqueue(final Callback<T> callback) {
  3. .........
  4. //okhttp的call实例
  5. okhttp3.Call call;
  6. Throwable failure;
  7. synchronized (this) {
  8. ..........
  9. executed = true;
  10. call = rawCall;
  11. failure = creationFailure;
  12. if (call == null && failure == null) {
  13. try {
  14. call = rawCall = createRawCall();
  15. } catch (Throwable t) {
  16. throwIfFatal(t);
  17. failure = creationFailure = t;
  18. }
  19. }
  20. }
  21. .......
  22. // 最终调用了okhttp的enqueue方法
  23. call.enqueue(
  24. new okhttp3.Callback() {
  25. @Override
  26. public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
  27. Response<T> response;
  28. try {
  29. //解析返回结果
  30. response = parseResponse(rawResponse);
  31. } catch (Throwable e) {
  32. throwIfFatal(e);
  33. callFailure(e);
  34. return;
  35. }
  36. .....
  37. }
  38. @Override
  39. public void onFailure(okhttp3.Call call, IOException e) {
  40. callFailure(e);
  41. }
  42. private void callFailure(Throwable e) {
  43. .......
  44. }
  45. });
  46. }

通过enqueue我们又发现了两条新的线路:createRawCall()方法(创建okhttp的call对象)以及parseResponse()方法(解析返回值)。
image.png

createRawCall

首先分析线路E如何创建okhttp.call的对象实例的。如下代码主要通过callFactory和requestFactory进行创建的,在创建OkHttpCall实例的时候传递进来的。

  1. private okhttp3.Call createRawCall() throws IOException {
  2. okhttp3.Call call = callFactory.newCall(requestFactory.create(args));
  3. if (call == null) {
  4. throw new NullPointerException("Call.Factory returned null.");
  5. }
  6. return call;
  7. }
  8. OkHttpCall(
  9. RequestFactory requestFactory,
  10. Object[] args,
  11. okhttp3.Call.Factory callFactory,
  12. Converter<ResponseBody, T> responseConverter) {
  13. this.requestFactory = requestFactory;
  14. this.args = args;
  15. this.callFactory = callFactory;
  16. this.responseConverter = responseConverter;
  17. }

我们沿着链路向上寻找.此时线路图如下:
image.png
查找流程:HttpServiceMethod.invoke -> HttpServiceMethod.parseAnnotations()
如下代码:callFactory和requestFactory是由外部传递进来的,继续向上查找

  1. static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
  2. Retrofit retrofit, Method method, RequestFactory requestFactory) {
  3. ......
  4. okhttp3.Call.Factory callFactory = retrofit.callFactory;
  5. if (!isKotlinSuspendFunction) {
  6. return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
  7. }
  8. .....
  9. }

代码如下:我们看到了RequestFactory,终于找到他了,进去看看干了些啥。

  1. abstract class ServiceMethod<T> {
  2. static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
  3. RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);
  4. Type returnType = method.getGenericReturnType();
  5. if (Utils.hasUnresolvableType(returnType)) {
  6. throw methodError(
  7. method,
  8. "Method return type must not include a type variable or wildcard: %s",
  9. returnType);
  10. }
  11. if (returnType == void.class) {
  12. throw methodError(method, "Service methods cannot return void.");
  13. }
  14. return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
  15. }
  16. }

RequestFactory: 可以看到主要是处理接口类service.class的方法的注解的

  1. RequestFactory build() {
  2. for (Annotation annotation : methodAnnotations) {
  3. parseMethodAnnotation(annotation);
  4. }
  5. ....
  6. }

处理完成之后会得到以下的值
image.png
我们回调线路E
image.png
在createRawCall()方法中调用了requestFactory.create()方法。

  1. private okhttp3.Call createRawCall() throws IOException {
  2. okhttp3.Call call = callFactory.newCall(requestFactory.create(args));
  3. if (call == null) {
  4. throw new NullPointerException("Call.Factory returned null.");
  5. }
  6. return call;
  7. }

requestFactory.create() 代码如下:最终就是得到了okhttp3.request这个RequestFactory其实就是拼接请求的

  1. okhttp3.Request create(Object[] args) throws IOException {
  2. @SuppressWarnings("unchecked") // It is an error to invoke a method with the wrong arg types.
  3. ParameterHandler<Object>[] handlers = (ParameterHandler<Object>[]) parameterHandlers;
  4. int argumentCount = args.length;
  5. .......
  6. RequestBuilder requestBuilder =
  7. new RequestBuilder(
  8. httpMethod,
  9. baseUrl,
  10. relativeUrl,
  11. headers,
  12. contentType,
  13. hasBody,
  14. isFormEncoded,
  15. isMultipart);
  16. if (isKotlinSuspendFunction) {
  17. // The Continuation is the last parameter and the handlers array contains null at that index.
  18. argumentCount--;
  19. }
  20. List<Object> argumentList = new ArrayList<>(argumentCount);
  21. for (int p = 0; p < argumentCount; p++) {
  22. argumentList.add(args[p]);
  23. handlers[p].apply(requestBuilder, args[p]);
  24. }
  25. return requestBuilder.get().tag(Invocation.class, new Invocation(method, argumentList)).build();
  26. }

那么线路E就理清楚了,其实就是okhttpclient.newCall(request)。这不就是okhttp的使用的api吗。
image.png
OK,requestFactory我们已经清楚了,其实就是对service class接口的方法中的注解处理,判断是get和post等等,然后返回okhttp3.request.

下面我们看callFactory: 从代码中可以看出是从retrofit.callFactory获取的,从build方法可以看到其实就是okHttpClient,我们也可以自己进行设置okHttpClient

  1. retrofit.callFactory
  2. public Retrofit build() {
  3. if (baseUrl == null) {
  4. throw new IllegalStateException("Base URL required.");
  5. }
  6. okhttp3.Call.Factory callFactory = this.callFactory;
  7. if (callFactory == null) {
  8. callFactory = new OkHttpClient();
  9. }
  10. ....
  11. }

image.png

我们再看一下梳理的线路:这样看会非常清晰的流程
image.png

parseResponse

下面我们在看parseResponse线路F是如何执行的。代码如下(在OkHttpCall类中):最终通过responseConverterconvert方法处理的

  1. Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
  2. ResponseBody rawBody = rawResponse.body();
  3. //.......
  4. ExceptionCatchingResponseBody catchingBody = new ExceptionCatchingResponseBody(rawBody);
  5. try {
  6. T body = responseConverter.convert(catchingBody);
  7. return Response.success(body, rawResponse);
  8. } catch (RuntimeException e) {
  9. // If the underlying source threw an exception, propagate that rather than indicating it was
  10. // a runtime exception.
  11. catchingBody.throwIfCaught();
  12. throw e;
  13. }
  14. }
  15. //responseConverter 同样也是在OkHttpCall的构造方法中创建的
  16. OkHttpCall(
  17. RequestFactory requestFactory,
  18. Object[] args,
  19. okhttp3.Call.Factory callFactory,
  20. Converter<ResponseBody, T> responseConverter) {
  21. this.requestFactory = requestFactory;
  22. this.args = args;
  23. this.callFactory = callFactory;
  24. this.responseConverter = responseConverter;
  25. }

所以我们得继续向上寻找:在HttpServiceMethodparseAnnotations方法中返回了responseConverter

  1. static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
  2. Retrofit retrofit, Method method, RequestFactory requestFactory) {
  3. .........
  4. Converter<ResponseBody, ResponseT> responseConverter =
  5. createResponseConverter(retrofit, method, responseType);
  6. okhttp3.Call.Factory callFactory = retrofit.callFactory;
  7. if (!isKotlinSuspendFunction) {
  8. return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
  9. }
  10. .....

我们来看一下createResponseConverter方法,调用了retrofit.responseBodyConverter

  1. private static <ResponseT> Converter<ResponseBody, ResponseT> createResponseConverter(
  2. Retrofit retrofit, Method method, Type responseType) {
  3. Annotation[] annotations = method.getAnnotations();
  4. try {
  5. return retrofit.responseBodyConverter(responseType, annotations);
  6. } catch (RuntimeException e) { // Wide exception range because factories are user code.
  7. throw methodError(method, e, "Unable to create converter for %s", responseType);
  8. }
  9. }

代码如下:其实就是去遍历converterFactories集合,这个集合存储着Converter,下面我们去找从哪里添加的Converter

  1. public <T> Converter<ResponseBody, T> responseBodyConverter(Type type, Annotation[] annotations) {
  2. return nextResponseBodyConverter(null, type, annotations);
  3. }
  4. .......
  5. public <T> Converter<ResponseBody, T> nextResponseBodyConverter(
  6. @Nullable Converter.Factory skipPast, Type type, Annotation[] annotations) {
  7. .....
  8. int start = converterFactories.indexOf(skipPast) + 1;
  9. for (int i = start, count = converterFactories.size(); i < count; i++) {
  10. Converter<ResponseBody, ?> converter =
  11. converterFactories.get(i).responseBodyConverter(type, annotations, this);
  12. if (converter != null) {
  13. //noinspection unchecked
  14. return (Converter<ResponseBody, T>) converter;
  15. }
  16. }
  17. }

找到了在Builder中,有一个设置的方法addConverterFactory

  1. /** Add converter factory for serialization and deserialization of objects. */
  2. public Builder addConverterFactory(Converter.Factory factory) {
  3. converterFactories.add(Objects.requireNonNull(factory, "factory == null"));
  4. return this;
  5. }

不知道大家是否还记得在开始的时候使用Retorfit的进行初始化,看到了没就是它addConverterFactory。我们添加了GsonConverterFactory就是通过gson去解析json数据转换为设置的javabean类。

  1. val retrofit = Retrofit.Builder()
  2. .baseUrl("https://api.github.com/")
  3. .addConverterFactory(GsonConverterFactory.create()) //gson的转换工厂
  4. .build()

OK,那么OkHttpCall的整个流程思路都梳理清晰了。我们再看一下流程图。其实我们从Retrofit的源码中可以学习到很多设计模式,学习优秀的代码
image.png

线路D -> adapt

我们继续回到HttpServiceMethod的invoke方法,去看adapt的具体实现。

  1. @Override
  2. final @Nullable ReturnT invoke(Object[] args) {
  3. Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
  4. return adapt(call, args);
  5. }

如下代码:adapt是HttpServiceMethod的抽象方法

  1. protected abstract @Nullable ReturnT adapt(Call<ResponseT> call, Object[] args);

那么它是如何实现的呢?我们继续回到parseAnnotations 这个方法返回了HttpServerMethod的实例,那么一定实现了adapt抽象方法的。

  1. if (!isKotlinSuspendFunction) { //这里主要判断 方法是否使用了kotlin的suspend标记,这里我们先不关心suspend是干什么的,一般是不用suspend的那么就会返回一个CallAdapted
  2. return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
  3. }
  4. ....

我们接着来看CallAdapted的实现, en….. 很奇怪,callAdapter是从外部传递进来的,通过外部传递进来的callAdapter调用adapt方法

  1. static final class CallAdapted<ResponseT, ReturnT> extends HttpServiceMethod<ResponseT, ReturnT> {
  2. private final CallAdapter<ResponseT, ReturnT> callAdapter;
  3. CallAdapted(
  4. RequestFactory requestFactory,
  5. okhttp3.Call.Factory callFactory,
  6. Converter<ResponseBody, ResponseT> responseConverter,
  7. CallAdapter<ResponseT, ReturnT> callAdapter) {
  8. super(requestFactory, callFactory, responseConverter);
  9. this.callAdapter = callAdapter;
  10. }
  11. @Override
  12. protected ReturnT adapt(Call<ResponseT> call, Object[] args) {
  13. return callAdapter.adapt(call);
  14. }
  15. }

我们还得要继续回到parseAnnotations 可以看到这样的一段代码:

  1. ....
  2. CallAdapter<ResponseT, ReturnT> callAdapter =
  3. createCallAdapter(retrofit, method, adapterType, annotations);
  4. ....
  5. if (!isKotlinSuspendFunction) {
  6. return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
  7. }
  8. ....

原来调用了createCallAdapter方法:诶…. 这个方法返回的callAdapter是由retrofit的callAdapter返回的。

  1. private static <ResponseT, ReturnT> CallAdapter<ResponseT, ReturnT> createCallAdapter(
  2. Retrofit retrofit, Method method, Type returnType, Annotation[] annotations) {
  3. try {
  4. //noinspection unchecked
  5. return (CallAdapter<ResponseT, ReturnT>) retrofit.callAdapter(returnType, annotations);
  6. } catch (RuntimeException e) { // Wide exception range because factories are user code.
  7. throw methodError(method, e, "Unable to create call adapter for %s", returnType);
  8. }
  9. }

继续回到Retrofit,代码如下:其实和上述讲的responseBodyConverter 类似可以由使用者自己定义进行设置,我们可以看到在nextCallAdapter只要遍历的adapter不等于null就会返回终止遍历,也就是说Retrofit只能有一个CallAdapter,Retrofit肯定有一个默认的CallAdapter因为我们在使用的时候并没有设置它

  1. public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) {
  2. return nextCallAdapter(null, returnType, annotations);
  3. }
  4. public CallAdapter<?, ?> nextCallAdapter(
  5. @Nullable CallAdapter.Factory skipPast, Type returnType, Annotation[] annotations) {
  6. .....
  7. int start = callAdapterFactories.indexOf(skipPast) + 1;
  8. for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
  9. // 获取CallAdapter
  10. CallAdapter<?, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this);
  11. if (adapter != null) {
  12. return adapter;
  13. }
  14. }
  15. ......
  16. }

我们去Retrofit.Builder.build()方法中查看,代码如下:

  1. public Retrofit build() {
  2. .......
  3. Executor callbackExecutor = this.callbackExecutor;
  4. if (callbackExecutor == null) {
  5. // 获取线程池 注意platform代表的是平台,一般分为Android和Java
  6. callbackExecutor = platform.defaultCallbackExecutor();
  7. }
  8. List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
  9. callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));
  10. .......
  11. }

我们进入Platform的defaultCallAdapterFactories

  1. // 获取platform 根据jvm的name不同进行获取
  2. private static Platform findPlatform() {
  3. return "Dalvik".equals(System.getProperty("java.vm.name"))
  4. ? new Android() //
  5. : new Platform(true);
  6. }
  7. List<? extends CallAdapter.Factory> defaultCallAdapterFactories(
  8. @Nullable Executor callbackExecutor) {
  9. DefaultCallAdapterFactory executorFactory = new DefaultCallAdapterFactory(callbackExecutor);
  10. return hasJava8Types
  11. ? asList(CompletableFutureCallAdapterFactory.INSTANCE, executorFactory)
  12. : singletonList(executorFactory);
  13. }
  14. // defaultCallbackExecutor的线程池的执行是在主线程中执行的
  15. static final class Android extends Platform {
  16. Android() {
  17. super(Build.VERSION.SDK_INT >= 24);
  18. }
  19. @Override
  20. public Executor defaultCallbackExecutor() {
  21. return new MainThreadExecutor();
  22. }
  23. @Nullable
  24. @Override
  25. Object invokeDefaultMethod(
  26. Method method, Class<?> declaringClass, Object object, Object... args) throws Throwable {
  27. if (Build.VERSION.SDK_INT < 26) {
  28. throw new UnsupportedOperationException(
  29. "Calling default methods on API 24 and 25 is not supported");
  30. }
  31. return super.invokeDefaultMethod(method, declaringClass, object, args);
  32. }
  33. static final class MainThreadExecutor implements Executor {
  34. // 主线程中的Handler
  35. private final Handler handler = new Handler(Looper.getMainLooper());
  36. @Override
  37. public void execute(Runnable r) {
  38. handler.post(r);
  39. }
  40. }
  41. }

再看一下,DefaultCallAdapterFactory,如何实现CallAdapter的。

  1. final class DefaultCallAdapterFactory extends CallAdapter.Factory {
  2. private final @Nullable Executor callbackExecutor;
  3. DefaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
  4. this.callbackExecutor = callbackExecutor;
  5. }
  6. @Override
  7. public @Nullable CallAdapter<?, ?> get(
  8. Type returnType, Annotation[] annotations, Retrofit retrofit) {
  9. //首先判断service 接口方法返回的是Call,如果不是则返回为null 继续循环匹配
  10. if (getRawType(returnType) != Call.class) {
  11. return null;
  12. }
  13. ........
  14. // 返回CallAdapter的实例
  15. return new CallAdapter<Object, Call<?>>() {
  16. @Override
  17. public Type responseType() {
  18. return responseType;
  19. }
  20. @Override
  21. public Call<Object> adapt(Call<Object> call) {
  22. return executor == null ? call : new ExecutorCallbackCall<>(executor, call);
  23. }
  24. };
  25. }
  26. // 对Call包装
  27. static final class ExecutorCallbackCall<T> implements Call<T> {
  28. final Executor callbackExecutor;
  29. final Call<T> delegate;
  30. // 传递过来一个线程池和delegateCall
  31. ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) {
  32. this.callbackExecutor = callbackExecutor;
  33. this.delegate = delegate;
  34. }
  35. @Override
  36. public void enqueue(final Callback<T> callback) {
  37. .....
  38. delegate.enqueue(
  39. new Callback<T>() {
  40. @Override
  41. public void onResponse(Call<T> call, final Response<T> response) {
  42. //进行线程切换,将回调在主线程中执行
  43. callbackExecutor.execute(
  44. () -> {
  45. if (delegate.isCanceled()) {
  46. // Emulate OkHttp's behavior of throwing/delivering an IOException on
  47. // cancellation.
  48. callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled"));
  49. } else {
  50. callback.onResponse(ExecutorCallbackCall.this, response);
  51. }
  52. });
  53. }
  54. .......
  55. });
  56. }
  57. }

其实默认的CallAdapter就做了一件事,就是线程切换,在主线程中进行一个回调。
那么如何自定义CallAdapter呢?我们知道默认的Retrofit的接口方法的返回值为Call,加入我们要使用RxJava,如何适配?

  1. @GET("users/{user}/repos")
  2. fun listReposRx(@Path("user") user:String?):Single<List<Repo>>
  3. val retrofit = Retrofit.Builder()
  4. .baseUrl("https://api.github.com/")
  5. .addConverterFactory(GsonConverterFactory.create()) //gson的转换工厂
  6. .addCallAdapterFactory(RxJava3CallAdapterFactory.create())// 添加RxJava支持
  7. .build()
  8. retrofit.create(GitHubService::class.java).listReposRx("octocat")
  9. .subscribe()

那么RxJavaCallAdapter是如何匹配RxJava的返回类型的呢?

  1. @Override
  2. public @Nullable CallAdapter<?, ?> get(
  3. Type returnType, Annotation[] annotations, Retrofit retrofit) {
  4. Class<?> rawType = getRawType(returnType);
  5. //根据他有的返回类型进行匹配的
  6. if (rawType == Completable.class) {
  7. // Completable is not parameterized (which is what the rest of this method deals with) so it
  8. // can only be created with a single configuration.
  9. return new RxJava3CallAdapter(
  10. Void.class, scheduler, isAsync, false, true, false, false, false, true);
  11. }
  12. boolean isFlowable = rawType == Flowable.class;
  13. boolean isSingle = rawType == Single.class;//我们上述的例子中就使用的是Single
  14. boolean isMaybe = rawType == Maybe.class;
  15. if (rawType != Observable.class && !isFlowable && !isSingle && !isMaybe) {
  16. return null;
  17. }
  18. .......
  19. }

Retrofit 如何确认多个返回类型不一致,该使用那个Adapter呢? 通过调用nextCallAdapter 去寻找目标的Adapter

  1. //Retrofit.java
  2. public CallAdapter<?, ?> nextCallAdapter(
  3. @Nullable CallAdapter.Factory skipPast, Type returnType, Annotation[] annotations) {
  4. Objects.requireNonNull(returnType, "returnType == null");
  5. Objects.requireNonNull(annotations, "annotations == null");
  6. int start = callAdapterFactories.indexOf(skipPast) + 1;
  7. for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
  8. CallAdapter<?, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this);
  9. if (adapter != null) {
  10. return adapter;
  11. }
  12. }
  13. ...
  14. }

在RxJava的Adapter中如何进行类型判断的:通过get方法判断返回值的类型是不是特有的RxJava的类型,如果不是返回null。
image.png

OK,那么Retrofit的完整的流程如下,通过线路的方式理清源码。
image.png