Retrofit源码流程分析

简单使用流程

以下是一个简单的Retrofit使用流程,在源码分析中只关注一些流程上的东西,忽略细节陷入细节的话很容易晕,好吧细节我也没咋看懂。。。

在这里插入图片描述

在这里插入图片描述

Step1 创建Retrofit实例

先看看Retrofit中的一些变量

public final class Retrofit {
  private final Map<Method, ServiceMethod<?>> serviceMethodCache = new ConcurrentHashMap<>();
  //很明显就是一个用于生成Okhttp的Call实例的工厂
  //后续会看到其实就是把OkhttpClient赋值给它
  final okhttp3.Call.Factory callFactory;
  //这就是上图中对应的.baseUrl("")这里传入了一个空字符串,当然实际项目中肯定不能这样
  //这只是为了方便,Retrofit会把传入的字符传转为HttpUrl对象
  final HttpUrl baseUrl;
  //保存自定义和默认的转换器,把响应数据转为特定格式
  final List<Converter.Factory> converterFactories;
  //保存自定义和默认的Call的适配器
  final List<CallAdapter.Factory> callAdapterFactories;
  //一个线程调度器
  final @Nullable Executor callbackExecutor;
  //一个标志位判断是否需求提前验证上图Api接口中的这些方法,并保存到map中
  final boolean validateEagerly;

  Retrofit(okhttp3.Call.Factory callFactory, HttpUrl baseUrl,
      List<Converter.Factory> converterFactories, List<CallAdapter.Factory> callAdapterFactories,
      @Nullable Executor callbackExecutor, boolean validateEagerly) {
    this.callFactory = callFactory;
    this.baseUrl = baseUrl;
    this.converterFactories = converterFactories; // Copy+unmodifiable at call site.
    this.callAdapterFactories = callAdapterFactories; // Copy+unmodifiable at call site.
    this.callbackExecutor = callbackExecutor;
    this.validateEagerly = validateEagerly;
  }

Retrofit.Builder()

首先来到Retrofit.Builder()中:截取部分代码片段
在这里插入图片描述
在这里插入图片描述
在Builder()中的代码很简单Platform.get()方法会来到Platform类的findPlatform()方法,方法名其实已经很明确了此方法和平台有关

 if (Build.VERSION.SDK_INT != 0) {
        return new Android();
      }

在Android开发中一定会调用到new Android()生成一个Android类型的实例,当然此实例对象是继承自Platform,来看一下它又做了什么

 static class Android extends Platform {
    @IgnoreJRERequirement // Guarded by API check.
    @Override boolean isDefaultMethod(Method method) {
      if (Build.VERSION.SDK_INT < 24) {
        return false;
      }
      return method.isDefault();
    }
    @Override public Executor defaultCallbackExecutor() {
      return new MainThreadExecutor();
    }
	
	//1:这里会返回一个默认的CallAdapter实例,具体后面分析
    @Override List<? extends CallAdapter.Factory> defaultCallAdapterFactories(
        @Nullable Executor callbackExecutor) {
      if (callbackExecutor == null) throw new AssertionError();
      DefaultCallAdapterFactory executorFactory = new DefaultCallAdapterFactory(callbackExecutor);
      return Build.VERSION.SDK_INT >= 24
        ? asList(CompletableFutureCallAdapterFactory.INSTANCE, executorFactory)
        : singletonList(executorFactory);
    }

    @Override int defaultCallAdapterFactoriesSize() {
      return Build.VERSION.SDK_INT >= 24 ? 2 : 1;
    }
	//2:这里返回一个默认的数据转换器
    @Override List<? extends Converter.Factory> defaultConverterFactories() {
      return Build.VERSION.SDK_INT >= 24
          ? singletonList(OptionalConverterFactory.INSTANCE)
          : Collections.<Converter.Factory>emptyList();
    }

    @Override int defaultConverterFactoriesSize() {
      return Build.VERSION.SDK_INT >= 24 ? 1 : 0;
    }
	//3:用于线程调度
    static class MainThreadExecutor implements Executor {
      private final Handler handler = new Handler(Looper.getMainLooper());

      @Override public void execute(Runnable r) {
        handler.post(r);
      }
    }
  }

总结:在Builder()中Platform.get()–>findPlatform()–>new Android()这一个流程走下来主要就是关联具体的平台,至于初始化实例对象就是在Android()中标记的那三点在build中会去调用,具体的作用后续会用到

Retrofit.Builder().build()

直接上代码

public Retrofit build() {
	  //baseUrl为null直接抛出异常
      if (baseUrl == null) {
        throw new IllegalStateException("Base URL required.");
      }
	  /**
	   *注意:这里就把this.callFactory赋值给Call.Factory了简单看一下它的初始化流程:
	   * public Builder client(OkHttpClient client) {
       * return callFactory(checkNotNull(client, "client == null"));}
       * 
       * public Builder callFactory(okhttp3.Call.Factory factory) {
       * this.callFactory = checkNotNull(factory, "factory == null");
       * return this;}
       * 从这两个方法就可以看出了callFactory就是一个OkhttpClient,即Call.Factory
       * 就是OkhttpClient,还记得Okhttp中的call怎么创建出来的吗?就是通过
       * OkHttpClient的newCall方法创建的,从这里大概能猜出为什么经常听到Retrofit底
       * 层是使用的Okhttp了
	   */
      okhttp3.Call.Factory callFactory = this.callFactory;
      if (callFactory == null) {
        callFactory = new OkHttpClient();
      }
	  /**
	   * 这里就是初始化Retrofit的线程调度器了,如果我们没有手动设置的话就会使用
	   * platform中初始化的那个线程调度器即:MainThreadExecutor
	   */
      Executor callbackExecutor = this.callbackExecutor;
      if (callbackExecutor == null) {
        callbackExecutor = platform.defaultCallbackExecutor();
      }

   	  /**
   	   * 后续的代码就是把默认的数据转换器以及call的适配器全部保存到list中,包括自己设置		
   	   * 以及Retrofit默认的
   	   */
      List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
      callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));

      // 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.
      converterFactories.add(new BuiltInConverters());
      converterFactories.addAll(this.converterFactories);
      converterFactories.addAll(platform.defaultConverterFactories());

      return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
          unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
    }

Step1就到此结束,总的来说就是初始化一些实例并保存下来

Step2 Retrofit.Create()

public <T> T create(final Class<T> service) {
    Utils.validateServiceInterface(service);
    //这里在Retrofit的变量就已经分析了
    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 @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);
            }
            //如果是默认方法(比如 Java8 ),就执行 platform 的默认方法。否则执行
            // loadServiceMethod方法的invoke方法
            if (platform.isDefaultMethod(method)) {
              return platform.invokeDefaultMethod(method, service, proxy, args);
            }
            return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
          }
        });
  }

这里一目了然核心就是一个动态代理,回到最开始的使用流程来看当调用api.fetchData方法之后会来到InvocationHandler的invoke中并最终调用loadServiceMethod方法,主要看最后一行loadServiceMethod(method).invoke(args != null ? args : emptyArgs),这里分两部分来看loadServiceMethod和invoke

loadServiceMethod

ServiceMethod<?> loadServiceMethod(Method method) {
    ServiceMethod<?> result = serviceMethodCache.get(method);
    if (result != null) return result;

    synchronized (serviceMethodCache) {
      result = serviceMethodCache.get(method);
      if (result == null) {
      	/**
      	 * 该方法核心就是为了获取ServiceMethod实例,以method为key首先在map中取
      	 * 如果没有就通过parseAnnotations去创建,并把已经构造出来的Retrofit实例
      	 * 和method传进去
      	 */
        result = ServiceMethod.parseAnnotations(this, method);
        serviceMethodCache.put(method, result);
      }
    }
    return result;
  }
/**
 * RequestFactory.parseAnnotations(retrofit, method)主要是解析方法的注解
 * 和参数的注解并保存下来
 * 
 * HttpServiceMethod.parseAnnotations主要是创建CallAdapter即请求的适配器
 * 以及Convert即数据转换器
 * 
 * 最终会返回一个HttpServiceMethod的具体实现类的实例对象
 * 具体代码后面再分析
 */
abstract class ServiceMethod<T> {
  static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
    RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);
	// ......省略
    return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
  }

  abstract @Nullable T invoke(Object[] args);
}

先梳理下流程:
1、首先Retrofit.Builder().build()这中间会去初始化一些实例比如默认的CallAdapter.Factory以及默认的数据转换器并保存,当然也会保存我们自己设置的,还会把OkhttpClient赋值给retrofit的Call.Factory变量最后创建Retrofit实例
2、通过动态代理在create中返回一个Api的proxy对象
3、当使用api.fetchData的时候来到invocationHandler的invoke中并最终调用loadServiceMethod(…).invoke(…)
4、创建一个HttpServiceMethod的具体实现类的实例对象,在创建的过程中首先通过RequestFactory.parseAnnotations去解析方法以及方法参数的注解,其次在HttpServiceMethod.parseAnnotations中还会创建CallAdapter、Convert
5、调用HttpServiceMethod的具体实例的invoke方法

RequestFactory.parseAnnotations

    RequestFactory build() {
      for (Annotation annotation : methodAnnotations) {
      //这里主要是解析method的注解如GET、POST等,获取其中的值并保存这里就是
      //{pageNo}/fetch 这部分很简单感兴趣可以看下
        parseMethodAnnotation(annotation);
      }
	 //省略部分代码...
      int parameterCount = parameterAnnotationsArray.length;
      parameterHandlers = new ParameterHandler<?>[parameterCount];
      for (int p = 0, lastParameter = parameterCount - 1; p < parameterCount; p++) {
        parameterHandlers[p] =
            parseParameter(p, parameterTypes[p], parameterAnnotationsArray[p], p == lastParameter);
      }
	  //省略部分代码...
      return new RequestFactory(this);
    }

    private @Nullable ParameterHandler<?> parseParameter(
        int p, Type parameterType, @Nullable Annotation[] annotations, boolean allowContinuation) {
      ParameterHandler<?> result = null;
      //这里主要是解析method参数的注解
      if (annotations != null) {
        for (Annotation annotation : annotations) {
          ParameterHandler<?> annotationAction =
              parseParameterAnnotation(p, parameterType, annotations, annotation);

          if (annotationAction == null) {
            continue;
          }

          if (result != null) {
            throw parameterError(method, p,
                "Multiple Retrofit annotations found, only one allowed.");
          }

          result = annotationAction;
        }
      }

      if (result == null) {
        if (allowContinuation) {
          try {
          	/**
          	 * 注意这里如果我们Api接口里面使用的是协程那么会把isKotlinSuspendFunction
          	 * 置为true,协程中的suspend方法转为java代码的时候就是这个Continuation类型
          	 */
            if (Utils.getRawType(parameterType) == Continuation.class) {
              isKotlinSuspendFunction = true;
              return null;
            }
          } catch (NoClassDefFoundError ignored) {
          }
        }
        throw parameterError(method, p, "No Retrofit annotation found.");
      }

      return result;
    }

HttpServiceMethod.parseAnnotations

  static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
      Retrofit retrofit, Method method, RequestFactory requestFactory) {
    boolean isKotlinSuspendFunction = requestFactory.isKotlinSuspendFunction;
    boolean continuationWantsResponse = false;
    boolean continuationBodyNullable = false;

    Annotation[] annotations = method.getAnnotations();
    Type adapterType;
    //1、这里就是在解析method参数注解的时候设置的,如果使用了协程那么会置为true
    if (isKotlinSuspendFunction) {
      Type[] parameterTypes = method.getGenericParameterTypes();
      Type responseType = Utils.getParameterLowerBound(0,
          (ParameterizedType) parameterTypes[parameterTypes.length - 1]);
      if (getRawType(responseType) == Response.class && responseType instanceof ParameterizedType) {
        responseType = Utils.getParameterUpperBound(0, (ParameterizedType) responseType);
        //2、continuationWantsResponse赋值为true
        continuationWantsResponse = true;
      } 
      adapterType = new Utils.ParameterizedTypeImpl(null, Call.class, responseType);
      annotations = SkipCallbackExecutorImpl.ensurePresent(annotations);
    } else {
      adapterType = method.getGenericReturnType();
    }
	//3、这里就是创建CallAdapter
    CallAdapter<ResponseT, ReturnT> callAdapter =
        createCallAdapter(retrofit, method, adapterType, annotations);
    Type responseType = callAdapter.responseType();
   	//4、创建数据转换器
    Converter<ResponseBody, ResponseT> responseConverter =
        createResponseConverter(retrofit, method, responseType);

	//5、retrofit.callFactory就是okhttpClient,在Retrofit...build()已经分析过
    okhttp3.Call.Factory callFactory = retrofit.callFactory;
    
    /**
     * 6、从这里就开始创建HttpServiceMethod的具体实现类了
     * 不是协程suspend的话就返回CallAdapted
     * 是协程就返回SuspendForResponse
     */
    if (!isKotlinSuspendFunction) {
      return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
    } else if (continuationWantsResponse) {
      return (HttpServiceMethod<ResponseT, ReturnT>) new SuspendForResponse<>(requestFactory,
          callFactory, responseConverter, (CallAdapter<ResponseT, Call<ResponseT>>) callAdapter);
    } else {
      return (HttpServiceMethod<ResponseT, ReturnT>) new SuspendForBody<>(requestFactory,
          callFactory, responseConverter, (CallAdapter<ResponseT, Call<ResponseT>>) callAdapter,
          continuationBodyNullable);
    }
  }

注意
1、创建的CallAdapter可能是系统默认的可能是我们自己设置的如RxJava3CallAdapterRxJava3CallAdapter是从RxJava3CallAdapterFactory中get()出来的,而RxJava3CallAdapterFactory就是通过addCallAdapterFactory(RxJava3CallAdapterFactory.create())设置的
2、通过判断协程suspend去创建不同的HttpServiceMethod的具体实现类

下面来看一下CallAdapter的创建流程通过一系列调用最终会来到nextCallAdapter方法中:

  public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType,
      Annotation[] annotations) {
    checkNotNull(returnType, "returnType == null");
    checkNotNull(annotations, "annotations == null");

    int start = callAdapterFactories.indexOf(skipPast) + 1;
    for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
     /**
      * callAdapterFactories在之前就介绍过,这里根据returnType去寻找CallAdapter
      * 比如:我们在Api中的fetchData returnType 类型为 Single,那么返回的就是 RxJava2CallAdapterFactory 所获取的 CallAdapter
      * 
      * 若returnType是Call<xxxBean>返回的就是默认的CallAdapter,即DefaultCallAdapterFactory.get获取到的
      * 而它也在Retrofit..build()中就已经设置到callAdapterFactories中了
      */
      CallAdapter<?, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this);
      if (adapter != null) {
        return adapter;
      }
    }
    //省略...
  }

再次回顾loadServiceMethod这一套流程
1、解析方法、方法参数的注解
2、创建CallAdapter(Convert的创建和它差不多)
3、创建HttpServiceMethod的具体实现类的实例对象并返回
实际上callAdapter使用的就是一个适配器模式,把我们的请求转换一次实际上底层还是使用的是Okhttp call.enqueue那套,而具体的HttpServiceMethod则是在invoke中去做一些其它处理,毕竟协程的请求和Rx这些肯定还是有不同的地方

invoke

别忘了在loadServiceMethod后紧跟着就调用了invoke方法,现在来看一下,

if (!isKotlinSuspendFunction) {
      return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
    } else if (continuationWantsResponse) {
      //noinspection unchecked Kotlin compiler guarantees ReturnT to be Object.
      return (HttpServiceMethod<ResponseT, ReturnT>) new SuspendForResponse<>(requestFactory,
          callFactory, responseConverter, (CallAdapter<ResponseT, Call<ResponseT>>) callAdapter);
    } else {
      //noinspection unchecked Kotlin compiler guarantees ReturnT to be Object.
      return (HttpServiceMethod<ResponseT, ReturnT>) new SuspendForBody<>(requestFactory,
          callFactory, responseConverter, (CallAdapter<ResponseT, Call<ResponseT>>) callAdapter,
          continuationBodyNullable);
    }

在HttpServiceMethod.parseAnnotations中最终通过isKotlinSuspendFunction创建了不同的HttpServiceMethod实例,默认情况下是CallAdapted,来看下它的处理,实际上不管是哪种实例,invoke都调用的是HttpServiceMethod的invoke,子类都只是重写了adapt方法。
在这里插入图片描述
在这里我们看到创建了一个Call对象,这个call对象是Retrofit中的,注意这里的参数有requestFactory, args, callFactory, responseConverter,requestFactory中封装了方法和方法参数的各种注解,args是反复的参数,callFactory实际上就是个OkhttpClient,responseConverter则是数据转换器。

下面先来看下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;
    }

	/**
	 * invoke会来到这里,而这里又调用的是callAdapter.adapt并把httpCall传进去了
	 * 我们现在讨论的是默认的情况,即addCallAdapterFactory这些都没设置
	 * 并且返回参数也是Call<xxxBean>,所以这里的callAdapter是从DefaultCallAdapterFactory的get()中获取的
	 */
    @Override protected ReturnT adapt(Call<ResponseT> call, Object[] args) {
      return callAdapter.adapt(call);
    }
  }

来看一下DefaultCallAdapterFactory的get()方法做了什么

  @Override public @Nullable CallAdapter<?, ?> get(
    /**
     * 这里直接new了一个CallAdapter的实例
     */
    return new CallAdapter<Object, Call<?>>() {
      @Override public Type responseType() {
        return responseType;
      }
	/**
	 * adapt最终又会来到这里并创建了ExecutorCallbackCall,注意参数处了传进来的HttpCall外还有线程调度器executor
	 */
      @Override public Call<Object> adapt(Call<Object> call) {
        return executor == null
            ? call
            : new ExecutorCallbackCall<>(executor, call);
      }
    };
  }

看下ExecutorCallbackCall,它实现了Retrofit的Call接口,到这里实际上就是loadServiceMethod(method).invoke(args != null ? args : emptyArgs)这段代码的终点了,它最终返回的是一个实现了Retrofit.Call的对象,这也说明了在上面的使用流程中fetchData后为什么还要调用enqueue()方法

  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) {
      checkNotNull(callback, "callback == null");
	 
      delegate.enqueue(new Callback<T>() {
        @Override public void onResponse(Call<T> call, final Response<T> response) {
          callbackExecutor.execute(new Runnable() {
            @Override public void run() {
              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(new Runnable() {
            @Override public void run() {
              callback.onFailure(ExecutorCallbackCall.this, t);
            }
          });
        }
      });
    }
	//省略...
  }

Step3 call.enqueue

我们得到的call对象实际上就是一个ExecutorCallbackCall对象,当调用enqueue的时候会来到delegate.enqueue(…)中,delegate实际上是一个HttpCall对象,具体的网络请求是在HttpCall中执行的,这里需要结合HttpCall中的代码来看

	//HttpCall
  @Override public void enqueue(final Callback<T> callback) {
    checkNotNull(callback, "callback == null");

    okhttp3.Call call;
    Throwable failure;

    synchronized (this) {
      if (executed) throw new IllegalStateException("Already executed.");
      executed = true;

      call = rawCall;
      failure = creationFailure;
      if (call == null && failure == null) {
        try {
         /**
          * 1、创建Okhttp.call,在createRawCall中还会根据requestFactory去创建okhttp3.Request
          * requestFactory中包含了请求的各种注解信息,毕竟只有call没有request肯定是不行的晒
          */
          call = rawCall = createRawCall();
        } catch (Throwable t) {
          throwIfFatal(t);
          failure = creationFailure = t;
        }
      }
    }

    if (failure != null) {
      callback.onFailure(this, failure);
      return;
    }

    if (canceled) {
      call.cancel();
    }
    // step2
    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;
        }

        try {
          callback.onResponse(OkHttpCall.this, response);
        } catch (Throwable t) {
          throwIfFatal(t);
          t.printStackTrace(); // TODO this is not great
        }
      }

      @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) {
          throwIfFatal(t);
          t.printStackTrace(); // TODO this is not great
        }
      }
    });
  }

注意step2,在DefaultCallAdapterFactory.ExecutorCallbackCall的enqueue方法暂且命名为enqueue1这里为enqueue2,执行的enqueue1实际上会来到enqueue2中,因为enqueue1中的call实际上是HttpCall类型,这里接收一个CallBack对象用于请求回调,我们知道网络请求肯定不能在主线程,这个时候一直说的excutor线程调度器就起作用了,当执行callback.onResponse或者callback.onFailure又会回到enqueue1中去,再利用excutor把线程给切会主线程中

到此一套完整的流程就结束了

CallAdapter的替换过程

之前讨论的是默认情况现在假如我们这样使用
在这里插入图片描述
在这里插入图片描述
我们通过addCallAdapterFactory添加了RxJava3CallAdapterFactory并且方法searchAndroidRepos返回的是Observable类型,现在重新回到HttpServiceMethod.parseAnnotations中直接看核心代码
在这里插入图片描述
在这里插入图片描述
最终还是来到retrofit的nextCallAdapter方法中,根据returnType Observable这个时候得到就是RxJava3CallAdapterFactory.get()返回的CallAdapter即:RxJava3CallAdapter,当然此时loadServiceMethod返回的HttpServiceMethod的具体实例还是CallAdapted,所以这个时候invoke最终会来到RxJava3CallAdapter的adapt方法中:

  @Override
  public Object adapt(Call<R> call) {
    //在这里把httpCall封装到Observable中了,剩下的也就是RxJava的事情了
    //不管怎样它最终还是会回到httpCall的enqueue中并且使用okhttp.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 RxJavaPlugins.onAssembly(observable);
  }

到目前为止,CallAdapter 怎么变成一个 RxJava2CallAdapter 以及它的具体调用,我们也就清楚了

Retrofit怎样支持kotlin协程的

还是回到HttpServiceMethod.parseAnnotations中来

  static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
      Retrofit retrofit, Method method, RequestFactory requestFactory) {
    boolean isKotlinSuspendFunction = requestFactory.isKotlinSuspendFunction;
    boolean continuationWantsResponse = false;
    // step1
    if (isKotlinSuspendFunction) {
      Type[] parameterTypes = method.getGenericParameterTypes();
      Type responseType = Utils.getParameterLowerBound(0,
          (ParameterizedType) parameterTypes[parameterTypes.length - 1]);
      if (getRawType(responseType) == Response.class && responseType instanceof ParameterizedType) {
        // Unwrap the actual body type from Response<T>.
        responseType = Utils.getParameterUpperBound(0, (ParameterizedType) responseType);
        //step2
        continuationWantsResponse = true;
      } 

    if (!isKotlinSuspendFunction) {
      return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
    } else if (continuationWantsResponse) {
      //step3
      return (HttpServiceMethod<ResponseT, ReturnT>) new SuspendForResponse<>(requestFactory,
          callFactory, responseConverter, (CallAdapter<ResponseT, Call<ResponseT>>) callAdapter);
    } 
  }

这里精简了代码直接看最主要的
1、step1在RequestFactory.parseAnnotations中已经解释过了,如果方法是协程suspend那么会被置位true
2、continuationWantsResponse置为true
3、HttpServiceMethod的具体实例为SuspendForResponse

invoke方法都还是调用的HttpServiceMethod中的invoke,这个之前就说过,这里直接来看SuspendForResponse的adapt方法

  static final class SuspendForResponse<ResponseT> extends HttpServiceMethod<ResponseT, Object> {
    private final CallAdapter<ResponseT, Call<ResponseT>> callAdapter;

    SuspendForResponse(RequestFactory requestFactory, okhttp3.Call.Factory callFactory,
        Converter<ResponseBody, ResponseT> responseConverter,
        CallAdapter<ResponseT, Call<ResponseT>> callAdapter) {
      super(requestFactory, callFactory, responseConverter);
      this.callAdapter = callAdapter;
    }

    @Override protected Object adapt(Call<ResponseT> call, Object[] args) {
    /**
     * step1
     * 注意这里的callAdapter还是默认的callAdapter即从DefaultCallAdapterFactory.get获取的
     * 所以这里的call实际上就是ExecutorCallbackCall
     */
      call = callAdapter.adapt(call);
      /**
       * step2
       * args[args.length - 1]取最后一个参数
       * 强转为Continuation类型
       */
      Continuation<Response<ResponseT>> continuation =
          (Continuation<Response<ResponseT>>) args[args.length - 1];
      try {
      	// step3
        return KotlinExtensions.awaitResponse(call, continuation);
      } catch (Exception e) {
        return KotlinExtensions.yieldAndThrow(e, continuation);
      }
    }
  }

准备好了后会调用KotlinExtensions.awaitResponse(call, continuation)

suspend fun <T : Any> Call<T>.awaitResponse(): Response<T> {
  return suspendCancellableCoroutine { continuation ->
    continuation.invokeOnCancellation {
      cancel()
    }
    /**
     * 这里用到了kotlin的扩展函数的特性,然后调用了call的enqueue方法
     */
    enqueue(object : Callback<T> {
      override fun onResponse(call: Call<T>, response: Response<T>) {
        continuation.resume(response)
      }

      override fun onFailure(call: Call<T>, t: Throwable) {
        continuation.resumeWithException(t)
      }
    })
  }
}

Continuation

这里解释一下KotlinExtensions.awaitResponse(call, continuation)这段代码

    @GET("search/repositories?sort=stars&q=Android")
    suspend fun searchAndroidRepos2(
        @Query("per_page") per_page: Int,
        @Query("page") page: Int
    ): RepoResponse

在这里插入图片描述

这两段代码和KotlinExtensions.awaitResponse的情况很相似都是java调用kotlin suspend方法的代码,awaitResponse方法没有参数为什么java调用需要传递两个参数

1、awaitResponse是Call的一个扩展方法java调用时候需要把Call对象传进去
2、java调用kotlin suspend方法的代码,需要在最后传递一个Continuation类型的参数

以上就是Retrofit对kotlin的支持

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值