阅读 1377

网络 | Retrofit 全面解析

「本文已参与好文召集令活动,点击查看:后端、大前端双赛道投稿,2万元奖池等你挑战!

Retrofit 全面解析

A type-safe HTTP client for Android and Java

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

Retrofit的使用

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

interface GitHubService {
    @GET("users/{user}/repos")
    fun listRepos(@Path("user") user:String?):Call<List<Repo>>
}
val retrofit = Retrofit.Builder()
            .baseUrl("https://api.github.com/")
            .addConverterFactory(GsonConverterFactory.create()) //gson的转换工厂
            .build()

        retrofit.create(GitHubService::class.java).listRepos("octocat")
            .enqueue(object :Callback<List<Repo>>{
                override fun onResponse(call: Call<List<Repo>>, response: Response<List<Repo>>) {
                    println(response.body()?.size)
                }

                override fun onFailure(call: Call<List<Repo>>, t: Throwable) {
                    TODO("Not yet implemented")
                }
            })
复制代码

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

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

从Create方法分析

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

val retrofit = Retrofit.Builder()
            .baseUrl("https://api.github.com/")
            .addConverterFactory(GsonConverterFactory.create()) //gson的转换工厂
            .build()
复制代码

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

  public <T> T create(final Class<T> service) {
    //1. 进行初始化验证service接口 先看一下这个方法
    validateServiceInterface(service);
    //2. 返回代理对象  
    return (T)
        //使用java提供的动态代理
        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);
              }
            });
  }
复制代码

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

  private void validateServiceInterface(Class<?> service) {
  	//这个class必须是一个接口,如果不是接口就会报错
    if (!service.isInterface()) {
      throw new IllegalArgumentException("API declarations must be interfaces.");
    }
    //将接口加入到队列中  
    Deque<Class<?>> check = new ArrayDeque<>(1);
    check.add(service);
    while (!check.isEmpty()) {
      //从队列中取出接口类  
      Class<?> candidate = check.removeFirst();
      //class 接口类 不能有泛型 如:GithubService<T> 会报错
      if (candidate.getTypeParameters().length != 0) {
        StringBuilder message =
            new StringBuilder("Type parameters are unsupported on ").append(candidate.getName());
        if (candidate != service) {
          message.append(" which is an interface of ").append(service.getName());
        }
        throw new IllegalArgumentException(message.toString());
      }
      //判断接口 是否还有继承 如果有继续循环  
      Collections.addAll(check, candidate.getInterfaces());
    }
	// 开关,validateEagerly 开发和正式 能够快速验证
    if (validateEagerly) {
      Platform platform = Platform.get();
      for (Method method : service.getDeclaredMethods()) {
          //过滤接口的默认方法和静态方法
        if (!platform.isDefaultMethod(method) && !Modifier.isStatic(method.getModifiers())) {
          //验证和加载接口类的方法  
          loadServiceMethod(method);
        }
      }
    }
  }
复制代码

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

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

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

动态代理

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

    return (T)
        //使用java提供的动态代理
        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;
                return platform.isDefaultMethod(method) //考虑java8的兼容问题
                    ? platform.invokeDefaultMethod(method, service, proxy, args) //如果是默认方法 直接调用默认方法
                    : loadServiceMethod(method).invoke(args);
              }
            });
复制代码

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

class ProxyGitHubService : GitHubService {
    val invocationHandler:InvocationHandler = InvocationHandler(object : (Any, Method, Array<Any>) -> Any{
        override fun invoke(p1: Any, p2: Method, p3: Array<Any>): Any {
            // 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);
        }
    })

    override fun listRepos(user: String?): Call<List<Repo>> {
        val method = GitHubService::class.java.getDeclaredMethod("listRepos",String::class.java)
        invocationHandler.invoke(this,method,user)
    }
}
复制代码

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

loadServiceMethod

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

  ServiceMethod<?> loadServiceMethod(Method method) {
    //获取缓存的取出来,serviceMethodCache就是一个Map集合  
    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类,是一个抽象类,invoke方法并没有实现,可以看到通过parseAnnotations方法返回了ServiceMethod类的实例对象,我们找到ServiceMethod的实现类HttpServiceMethod类。 这里我们先把关注点放到invoke方法上,

abstract class ServiceMethod<T> {
  static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
    // 解析方法的注解,返回值类型,传递的参数  
    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);
}
复制代码

HttpServiceMethod

我们先看invoke方法的实现:

  @Override
  final @Nullable ReturnT invoke(Object[] args) {
    Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
    return adapt(call, args);
  }
复制代码

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

线路C -> OkHttpCall

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

interface GitHubService {
    @GET("users/{user}/repos")
    fun listRepos(@Path("user") user:String?):Call<List<Repo>>
}
复制代码

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

@Override
  public void enqueue(final Callback<T> callback) {
    .........
    //okhttp的call实例
    okhttp3.Call call;
    Throwable failure;
    synchronized (this) {
      ..........
      executed = true;
      call = rawCall;
      failure = creationFailure;
      if (call == null && failure == null) {
        try {
          call = rawCall = createRawCall();
        } catch (Throwable t) {
          throwIfFatal(t);
          failure = creationFailure = t;
        }
      }
    }
	.......
	// 最终调用了okhttp的enqueue方法
    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;
            }
            .....
          }

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

          private void callFailure(Throwable e) {
            .......
          }
        });
  }
复制代码

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

createRawCall

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

  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;
  }
  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;
  }
复制代码

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

  static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
      Retrofit retrofit, Method method, RequestFactory requestFactory) {
      ......
          okhttp3.Call.Factory callFactory = retrofit.callFactory;
    if (!isKotlinSuspendFunction) {
      return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
    }
    .....
  }
复制代码

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

abstract class ServiceMethod<T> {
  static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
    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);
  }
}
复制代码

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

    RequestFactory build() {
      for (Annotation annotation : methodAnnotations) {
        parseMethodAnnotation(annotation);
      }
      ....
    }
复制代码

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

  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.create() 代码如下:最终就是得到了okhttp3.request这个RequestFactory其实就是拼接请求的

  okhttp3.Request create(Object[] args) throws IOException {
    @SuppressWarnings("unchecked") // It is an error to invoke a method with the wrong arg types.
    ParameterHandler<Object>[] handlers = (ParameterHandler<Object>[]) parameterHandlers;

    int argumentCount = args.length;
.......

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

    if (isKotlinSuspendFunction) {
      // The Continuation is the last parameter and the handlers array contains null at that index.
      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();
  }
复制代码

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

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

retrofit.callFactory

    public Retrofit build() {
      if (baseUrl == null) {
        throw new IllegalStateException("Base URL required.");
      }

      okhttp3.Call.Factory callFactory = this.callFactory;
      if (callFactory == null) {
        callFactory = new OkHttpClient();
      }
      ....
    }

复制代码

image.png

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

parseResponse

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

  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);
    } catch (RuntimeException e) {
      // If the underlying source threw an exception, propagate that rather than indicating it was
      // a runtime exception.
      catchingBody.throwIfCaught();
      throw e;
    }
  }
  
  //responseConverter 同样也是在OkHttpCall的构造方法中创建的
    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;
  }
复制代码

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

  static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
      Retrofit retrofit, Method method, RequestFactory requestFactory) {
    .........

    Converter<ResponseBody, ResponseT> responseConverter =
        createResponseConverter(retrofit, method, responseType);

    okhttp3.Call.Factory callFactory = retrofit.callFactory;
    if (!isKotlinSuspendFunction) {
      return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
    } 
    .....
复制代码

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

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

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

  public <T> Converter<ResponseBody, T> responseBodyConverter(Type type, Annotation[] annotations) {
    return nextResponseBodyConverter(null, type, annotations);
  }
  .......
  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;
      }
    }
  }
复制代码

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

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

复制代码

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

val retrofit = Retrofit.Builder()
            .baseUrl("https://api.github.com/")
            .addConverterFactory(GsonConverterFactory.create()) //gson的转换工厂
            .build()
复制代码

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

线路D -> adapt

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

  @Override
  final @Nullable ReturnT invoke(Object[] args) {
    Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
    return adapt(call, args);
  }
复制代码

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

protected abstract @Nullable ReturnT adapt(Call<ResponseT> call, Object[] args);
复制代码

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

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

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

  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);
    }
  }
复制代码

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

....   
CallAdapter<ResponseT, ReturnT> callAdapter =
        createCallAdapter(retrofit, method, adapterType, annotations);
....
if (!isKotlinSuspendFunction) {
      return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
    }
....
复制代码

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

  private static <ResponseT, ReturnT> CallAdapter<ResponseT, ReturnT> createCallAdapter(
      Retrofit retrofit, Method method, Type returnType, Annotation[] annotations) {
    try {
      //noinspection unchecked
      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,代码如下:其实和上述讲的responseBodyConverter 类似可以由使用者自己定义进行设置,我们可以看到在nextCallAdapter只要遍历的adapter不等于null就会返回终止遍历,也就是说Retrofit只能有一个CallAdapter,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  
      CallAdapter<?, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this);
      if (adapter != null) {
        return adapter;
      }
    }
    ......
  }
复制代码

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

public Retrofit build() {
      .......
      Executor callbackExecutor = this.callbackExecutor;
      if (callbackExecutor == null) {
        // 获取线程池 注意platform代表的是平台,一般分为Android和Java  
        callbackExecutor = platform.defaultCallbackExecutor();
      }
      List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
      callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));
      .......
}
复制代码

我们进入Platform的defaultCallAdapterFactories

// 获取platform 根据jvm的name不同进行获取  
private static Platform findPlatform() {
    return "Dalvik".equals(System.getProperty("java.vm.name"))
        ? new Android() //
        : new Platform(true);
  }  
List<? extends CallAdapter.Factory> defaultCallAdapterFactories(
      @Nullable Executor callbackExecutor) {
    DefaultCallAdapterFactory executorFactory = new DefaultCallAdapterFactory(callbackExecutor);
    return hasJava8Types
        ? asList(CompletableFutureCallAdapterFactory.INSTANCE, executorFactory)
        : singletonList(executorFactory);
  }
   // defaultCallbackExecutor的线程池的执行是在主线程中执行的
    static final class Android extends Platform {
    Android() {
      super(Build.VERSION.SDK_INT >= 24);
    }

    @Override
    public Executor defaultCallbackExecutor() {
      return new MainThreadExecutor();
    }

    @Nullable
    @Override
    Object invokeDefaultMethod(
        Method method, Class<?> declaringClass, Object object, Object... args) throws Throwable {
      if (Build.VERSION.SDK_INT < 26) {
        throw new UnsupportedOperationException(
            "Calling default methods on API 24 and 25 is not supported");
      }
      return super.invokeDefaultMethod(method, declaringClass, object, args);
    }

    static final class MainThreadExecutor implements Executor {
      // 主线程中的Handler  
      private final Handler handler = new Handler(Looper.getMainLooper());

      @Override
      public void execute(Runnable r) {
        handler.post(r);
      }
    }
  }
复制代码

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

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) {
    //首先判断service 接口方法返回的是Call,如果不是则返回为null 继续循环匹配  
    if (getRawType(returnType) != Call.class) {
      return null;
    }
    ........
    // 返回CallAdapter的实例 
    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);
      }
    };
  }
  
  // 对Call包装
  static final class ExecutorCallbackCall<T> implements Call<T> {
    final Executor callbackExecutor;
    final Call<T> delegate;
    // 传递过来一个线程池和delegateCall
    ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) {
      this.callbackExecutor = callbackExecutor;
      this.delegate = delegate;
    }

    @Override
    public void enqueue(final Callback<T> callback) {
      .....
      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);
                    }
                  });
            }

            .......
          });
    }
  }

复制代码

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

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

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

@Override
  public @Nullable CallAdapter<?, ?> get(
      Type returnType, Annotation[] annotations, Retrofit retrofit) {
    Class<?> rawType = getRawType(returnType);
    //根据他有的返回类型进行匹配的
    if (rawType == Completable.class) {
      // Completable is not parameterized (which is what the rest of this method deals with) so it
      // can only be created with a single configuration.
      return new RxJava3CallAdapter(
          Void.class, scheduler, isAsync, false, true, false, false, false, true);
    }

    boolean isFlowable = rawType == Flowable.class;
    boolean isSingle = rawType == Single.class;//我们上述的例子中就使用的是Single
    boolean isMaybe = rawType == Maybe.class;
    if (rawType != Observable.class && !isFlowable && !isSingle && !isMaybe) {
      return null;
    }
    .......
  }
复制代码

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

文章分类
Android
文章标签