Retrofit 源码分析

Posted 安卓开发-顺

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Retrofit 源码分析相关的知识,希望对你有一定的参考价值。

上一篇文章我们分析了OKHttp3的源码,趁热打铁我们接着分析下Retrofit的源码。

目录

一、构建过程

二、接口执行


首先,先明确一个问题,Retrofit并不是一个网络框架,它是一个对OKHttp的使用封装框架,其内部依赖了OKHttp,真正的网络请求都是由OKHttp来实现。

先来看下Retrofit的基本用法:

//第一步 构建Retrofit对象
Retrofit mRetrofit = new Retrofit.Builder()
            .baseUrl(ServerConfigLocalConstants.SERVER_UP_URL)
            .client(builder.build())
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .addConverterFactory(GsonConverterFactory.create())
            .build();

//第二步 发起请求
Observable<CommentDTO> observable = mRetrofit.create(CommonServiceInterface.class).addComment(xxx,xxx);

observable.subscribeOn(Schedulers.io()).observeOn(androidSchedulers.mainThread()).subscribe(...

 其中:CommonServiceInterface接口定义如下:

public interface CommonServiceInterface 

    /**
     * 添加评论内容
     *
     * @return
     */
    @POST("/personalization-service/v1/comment")
    Observable<CommentDTO> addComment(@Header("Authorization") String token, @Body     
                                      CommentAddDTO commentAddDTO);

一、构建过程

我们看基本用法中的第一步 构建Retrofit:

  • .baseUrl(xxx) 设置默认服务器的地址
    
  • .client(builder.build()) 这里传入的是OKHttpClient
  • .addCallAdapterFactory(RxJava2CallAdapterFactory.create())  添加请求适配器工厂,这里我们加入了RxJava2CallAdapterFactory
  • .addConverterFactory(GsonConverterFactory.create()) 添加转换工厂 这里我们加入了GsonConverterFactory
  • .build() 构建Retrofit对象

下面我们看build()源码,去看下设置的参数是如何处理的,请注意看注释信息:

package retrofit2;

public final class Retrofit 

...
    public Retrofit build() 
      ...

      //这个就是校验我们传入的.client如果没传就默认创建一个OkHttpClient()
      okhttp3.Call.Factory callFactory = this.callFactory;
      if (callFactory == null) 
        callFactory = new OkHttpClient();
      
      //用来做线程切换的Executor 回调方法执行器
      Executor callbackExecutor = this.callbackExecutor;
      if (callbackExecutor == null) 
        callbackExecutor = platform.defaultCallbackExecutor();
      

      // 网络请求适配器工厂集合,这里的this.callAdapterFactories就包含了我们
      // 通过addCallAdapterFactory加入的RxJava2CallAdapterFactory
      List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
      //添加默认的网络请求适配器工厂
      callAdapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));

      // 数据转换器工厂的集合
      List<Converter.Factory> converterFactories =
          new ArrayList<>(1 + this.converterFactories.size());

      // 添加内部默认的工厂
      converterFactories.add(new BuiltInConverters());
      // 添加外部配置的工厂,这里的this.converterFactories 就包含了我们通过
      // addConverterFactory添加的 GsonConverterFactory
      converterFactories.addAll(this.converterFactories);

      // 最终new出 Retrofit 传入以上参数
      return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
          unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
    
  

首先来解释下这段代码,为何是用来线程切换的:

//用来做线程切换的Executor 回调方法执行器
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) 
     callbackExecutor = platform.defaultCallbackExecutor();

 这里的callbackExecutor我们一般不用设置,因此会默认使用     

 platform.defaultCallbackExecutor()

进去看下源码实现:


package retrofit2;

...

class Platform 
 

...
  static class Android extends Platform 
    @Override public Executor defaultCallbackExecutor() 
      //这里直接创建  MainThreadExecutor 根据名称就可以推断 主线程执行器
      // 就是让任务在主线程执行
      return new MainThreadExecutor();
    

    @Override CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) 
      if (callbackExecutor == null) throw new AssertionError();
      return new ExecutorCallAdapterFactory(callbackExecutor);
    

    //看到这里了的Handler传入的是Looper.getMainLooper() 就更确认无疑了
    //就是把切换到主线程执行任务  利用 handler.post实现
    static class MainThreadExecutor implements Executor 
      private final Handler handler = new Handler(Looper.getMainLooper());

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

 callbackExecutor 我们弄清楚后,继续往下看:

这里的网络请求适配器工厂集合中目前有两个工厂:

  1. 我们在构建时加入的RxJava2CallAdapterFactory
  2. platform.defaultCallAdapterFactory(callbackExecutor)); 

其中第二个是ExecutorCallAdapterFactory,还传入了刚才的callbackExecutor

 既然加入了两个工厂,那执行接口请求的时候到底用哪个呢?这里在下面接口执行中会分析,这里先剧透下,Retrofit会根据我们定义的方法的返回值来选择:

  • 我们这里的返回值是Observable<CommentDTO>,(Observable是Rxjava里面的)那么就会选择RxJava2CallAdapterFactory生产出来的RxJava2CallAdapter
  • 如果返回值是Retrofit包下的Call<ResponseBody>,那么就会使用ExecutorCallAdapterFactory生产出来的 CallAdapter

最后一部分是数据转换器工厂的集合 converterFactories ,这个主要负责把json转换成我们具体的对象,这个用gson(Retrofit有默认实现GsonConverterFactory)或者fastjson(内部有Retrofit2ConverterFactory)都可以。

数据转换工厂集合中还加入了默认的BuiltInConverters,这个有什么作用呢?后面会分析到,请继续往下看。

二、接口执行

我们看一开始中提到的基本用法中的第二步

//第二步 发起请求
Observable<CommentDTO> observable = mRetrofit.create(CommonServiceInterface.class).addComment(xxx,xxx);

我们来看下这一步,背后发生了什么,先进入create方法:

 我们看到 Retrofit 的 create方法就是通过动态代理创建了一个代理类,然后返回。

这里利用动态代理的好处:

  • 可以控制我们定义的所有的请求方法,从而提取方法中的注解、参数
  • 为每一个请求分配适配的网络请求适配器callAdapterFactories 
  • 其他扩展处理

接下来我们看动态代理里面的invoke方法何时被执行呢?

比如当前的例子,执行.addComment(xxx,xxx);的时候就会触发invoke方法的执行并返回Observable,我们来分析源码,看看是如何做到的?

  public <T> T create(final Class<T> service) 
    ...
    return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[]  service ,
        new InvocationHandler() 

          //这里得到的是 static class Android extends Platform ...
          private final Platform platform = Platform.get();

          @Override public Object invoke(Object proxy, Method method, @Nullable Object[] args)
              throws Throwable 
            // 如果当前方法不是当前接口类里面自己定义的方法,而是Object里面的方法则
            // 直接返回默认处理 例如Object类里面的一些public定义的 wait notify notifyAll等方法
            // 要知道Object是一切类的父类
            if (method.getDeclaringClass() == Object.class) 
              return method.invoke(this, args);
            
            // 在Android里面默认是false
            if (platform.isDefaultMethod(method)) 
              return platform.invokeDefaultMethod(method, service, proxy, args);
            

            // 非常关键的代码1 后面展开分析
            ServiceMethod<Object, Object> serviceMethod =
                (ServiceMethod<Object, Object>) loadServiceMethod(method);
            OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
            // 非常关键的代码2 后面展开分析  
            return serviceMethod.adapt(okHttpCall);
          
        );
  

上面对invoke方法做了逐行解析,下面看里面的关键代码1:

 ServiceMethod<Object, Object> serviceMethod =
               (ServiceMethod<Object, Object>) loadServiceMethod(method);

进入loadServiceMethod里面一探究竟,注意这里把method作为参数传入了:

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

    synchronized (serviceMethodCache) 
      result = serviceMethodCache.get(method);
      if (result == null) 
        result = new ServiceMethod.Builder<>(this, method).build();
        serviceMethodCache.put(method, result);
      
    
    return result;
  

 这里做了个缓存处理,如果已经存在了直接从缓存来取,我们看缓存没有去创建的情况:

result = new ServiceMethod.Builder<>(this, method).build();

看build()方法:

package retrofit2;
final class ServiceMethod<R, T> 
...
    Builder(Retrofit retrofit, Method method) 
      this.retrofit = retrofit;
      this.method = method;
      this.methodAnnotations = method.getAnnotations();
      this.parameterTypes = method.getGenericParameterTypes();
      this.parameterAnnotationsArray = method.getParameterAnnotations();
    

    public ServiceMethod build() 
      // 一上来就是重头戏 获取callAdapter 比如:RxJava2CallAdapterFactory,后面会展开分析
      callAdapter = createCallAdapter();
      responseType = callAdapter.responseType();

      //校验返回值类型
      ...

      // 又一个重头戏 创建数据转换器 比如 GsonConverterFactory 后面展开分析
      responseConverter = createResponseConverter();

      //解析方法上的注释 比如@GET/@POST等
      for (Annotation annotation : methodAnnotations) 
        parseMethodAnnotation(annotation);
      

      // 必须通过注解指定请求方式
      if (httpMethod == null) 
        throw methodError("HTTP method annotation is required (e.g., @GET, @POST, etc.).");
      
      // 省略校验工作
      ...
      //上面处理了方法注解,下面开始处理参数注解 比如 @Query @Path之类的参数注解
      int parameterCount = parameterAnnotationsArray.length;
      parameterHandlers = new ParameterHandler<?>[parameterCount];
      for (int p = 0; p < parameterCount; p++) 
        Type parameterType = parameterTypes[p];
        ...
        Annotation[] parameterAnnotations = parameterAnnotationsArray[p];
        ...
        //解析参数注解并保存到parameterHandlers里面
        parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);
      
      ...
      return new ServiceMethod<>(this);
    


build()方法有很多关键代码,第一个:callAdapter = createCallAdapter();

获取callAdapter(网络请求适配器) 比如我们当前例子中会得到:RxJava2CallAdapterFactory

进入createCallAdapter 看源码:

    private CallAdapter<T, R> createCallAdapter() 
      // 获取方法返回类型
      Type returnType = method.getGenericReturnType();
      ...
      // 获取方法注解
      Annotation[] annotations = method.getAnnotations();
      try 
        // 根据方法注解和返回类型得到CallAdapter
        return (CallAdapter<T, R>) retrofit.callAdapter(returnType, annotations);
       catch (RuntimeException e) 
      
    

 继续跟进retrofit.callAdapter(returnType, annotations)方法

  public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) 
    return nextCallAdapter(null, returnType, annotations);
  

又调用了 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<?, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this);
      if (adapter != null) 
        return adapter;
      
    
    ...
  

 这里循环遍历了所有工厂,其实我们当前例子中工厂集合里面就俩工厂(第一部分中已经分析)

  • RxJava2CallAdapterFactory
  • ExecutorCallAdapterFactory

所以说白了就是调用这两个工厂的get方法,如果返回值不是空 就返回对应结果,不在继续寻找。

因为我们当前的返回值是Observable 所以应该是返回RxJava2CallAdapter,下面去RxJava2CallAdapterFactory的get方法来看下:

  @Override
  public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) 
    Class<?> rawType = getRawType(returnType);

    // 返回类型是 Completable 直接返回 RxJava2CallAdapter
    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;
    //因为这里rawType 就是 Observable.class 所以不会返回 null
    if (rawType != Observable.class && !isFlowable && !isSingle && !isMaybe) 
      return null;
    

    boolean isResult = false;
    boolean isBody = false;
    Type responseType;
    ...
    //给 responseType isResult  isBody 赋值
    ...
    //返回RxJava2CallAdapter
    return new RxJava2CallAdapter(responseType, scheduler, isAsync, isResult, isBody, isFlowable,
        isSingle, isMaybe, false);
  

 通过源码看出 get方法最后返回的是RxJava2CallAdapter,这里我们顺便看下ExecutorCallAdapterFactory的get方法:

  @Override
  public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) 
    // 只要返回类型不是Call 就返回 null,那换句话说 只要是Call 就会返回下面创建的 CallAdapter
    if (getRawType(returnType) != Call.class) 
      return null;
    
    final Type responseType = Utils.getCallResponseType(returnType);
    //直接 new出CallAdapter 返回
    return new CallAdapter<Object, Call<?>>() 
      @Override public Type responseType() 
        return responseType;
      

      @Override public Call<Object> adapt(Call<Object> call) 
        return new ExecutorCallbackCall<>(callbackExecutor, call);
      
    ;
  

 如果返回结果是Call类型 就是命中ExecutorCallAdapterFactory,然后生成一个CallAdapter出来。

OK,我们回到ServiceMethod的 build方法

package retrofit2;
final class ServiceMethod<R, T> 
...
    public ServiceMethod build() 
      // 一上来就是重头戏 获取callAdapter 比如:RxJava2CallAdapterFactory,后面会展开分析
      callAdapter = createCallAdapter();
      responseType = callAdapter.responseType();

      // 又一个重头戏 创建数据转换器 比如 GsonConverterFactory 后面展开分析
      responseConverter = createResponseConverter();
      ...
      return new ServiceMethod<>(this);
    


 当前例子中,这里的callAdater 就是RxJava2CallAdapter,继续往下走来看

responseConverter = createResponseConverter();

    private Converter<ResponseBody, T> createResponseConverter() 
      Annotation[] annotations = method.getAnnotations();
      try 
        return retrofit.responseBodyConverter(responseType, annotations);
       catch (RuntimeException e) 
      
    

 继续看responseBodyConverter方法

  public <T> Converter<ResponseBody, T> responseBodyConverter(Type type, Annotation[] annotations) 
    return nextResponseBodyConverter(null, type, annotations);
  

有没有发现和网络请求适配器思路很像, 继续跟进到nextResponseBodyConverter

public <T> Converter<ResponseBody, T> nextResponseBodyConverter(
      @Nullable Converter.Factory skipPast, Type type, Annotation[] annotations) 
    ...

    int start = converterFactories.indexOf(skipPast) + 1;
    // 遍历所有转换器工厂 执行responseBodyConverter方法 不为空则返回
    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;
      
    

    ...
  

 这里就本例而言有两个转换器工厂:

  • BuiltInConverters(默认添加)
  • GsonConverterFactory(我们主动添加的)

这里会循环遍历去执行,默认先执行BuiltInConverters,我们先来看看BuiltInConverters能处理那些数据

final class BuiltInConverters extends Converter.Factory 
  @Override
  public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
      Retrofit retrofit) 
    if (type == ResponseBody.class) 
      return Utils.isAnnotationPresent(annotations, Streaming.class)
          ? StreamingResponseBodyConverter.INSTANCE
          : BufferingResponseBodyConverter.INSTANCE;
    
    if (type == Void.class) 
      return VoidResponseBodyConverter.INSTANCE;
    
    return null;
  

可以看到,如果具体的返回值类型是ResponseBody 或者Void ,BuiltInConverters就返回对应的Converter,这就意味着不会在用GsonConverterFactory

剩余的类型肯定要继续判断,就得GsonConverterFactory来处理了

    public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) 
        TypeAdapter<?> adapter = this.gson.getAdapter(TypeToken.get(type));
        return new GsonResponseBodyConverter(this.gson, adapter);
    

直接 new 了一个GsonResponseBodyConverter返回。

注意:如果使用GsonResponseBodyConverter遇到了这样的报错:

Expected a string but was BEGIN_OBJECT at line 1 column 2 path $

 是因为当提交的Body或者Response是String.class或八大基本数据类型(Integer.class,Long.class ...)Gson 不支持,解决办法:

  1. 换一个支持的比如 fastjson提供的 Retrofit2ConverterFactory
  2. 新加一个factory专门处理这些类型,(要加在GsonConverterFactory前面)
    1. implementaton 'com.squareup.retrofit2:converter-scalars:2.0.2'
    2. Retrofit mRetrofit = new Retrofit.Builder()
                  .baseUrl(ServerConfigLocalConstants.SERVER_UP_URL)
                  .client(builder.build())
                  .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                  //加在这个位置 在 GsonConverterFactory 前面
                  .addConverterFactory(ScalarsConverterFactory.create())
                  .addConverterFactory(GsonConverterFactory.create())
                  .build();

我们再次回到ServiceMethod的build方法,这里在贴出一次代码

package retrofit2;
final class ServiceMethod<R, T> 
...
    Builder(Retrofit retrofit, Method method) 
      this.retrofit = retrofit;
      this.method = method;
      this.methodAnnotations = method.getAnnotations();
      this.parameterTypes = method.getGenericParameterTypes();
      this.parameterAnnotationsArray = method.getParameterAnnotations();
    

    public ServiceMethod build() 
      // 一上来就是重头戏 获取callAdapter 比如:RxJava2CallAdapterFactory,后面会展开分析
      callAdapter = createCallAdapter();
      responseType = callAdapter.responseType();

      //校验返回值类型
      ...

      // 又一个重头戏 创建数据转换器 比如 GsonConverterFactory 后面展开分析
      responseConverter = createResponseConverter();

      //解析方法上的注释 比如@GET/@POST等
      for (Annotation annotation : methodAnnotations) 
        parseMethodAnnotation(annotation);
      

      // 必须通过注解指定请求方式
      if (httpMethod == null) 
        throw methodError("HTTP method annotation is required (e.g., @GET, @POST, etc.).");
      
      // 省略校验工作
      ...
      //上面处理了方法注解,下面开始处理参数注解 比如 @Query @Path之类的参数注解
      int parameterCount = parameterAnnotationsArray.length;
      parameterHandlers = new ParameterHandler<?>[parameterCount];
      for (int p = 0; p < parameterCount; p++) 
        Type parameterType = parameterTypes[p];
        ...
        Annotation[] parameterAnnotations = parameterAnnotationsArray[p];
        ...
        //解析参数注解并保存到parameterHandlers里面
        parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);
      
      ...
      return new ServiceMethod<>(this);
    


callAdapter 和 responseAdapter现在都有了,接下来该解析方法注解了:

//解析方法上的注释 比如@GET/@POST等
      for (Annotation annotation : methodAnnotations) 
        parseMethodAnnotation(annotation);
      

来看下parseMethodAnnotation方法

    private void parseMethodAnnotation(Annotation annotation) 
      if (annotation instanceof DELETE) 
        parseHttpMethodAndPath("DELETE", ((DELETE) annotation).value(), false);
       else if (annotation instanceof GET) 
        parseHttpMethodAndPath("GET", ((GET) annotation).value(), false);
       else if (annotation instanceof HEAD) 
        parseHttpMethodAndPath("HEAD", ((HEAD) annotation).value(), false);
        if (!Void.class.equals(responseType)) 
          throw methodError("HEAD method must use Void as response type.");
        
       else if (annotation instanceof PATCH) 
        parseHttpMethodAndPath("PATCH", ((PATCH) annotation).value(), true);
       else if (annotation instanceof POST) 
        parseHttpMethodAndPath("POST", ((POST) annotation).value(), true);
       else if (annotation instanceof PUT) 
        parseHttpMethodAndPath("PUT", ((PUT) annotation).value(), true);
       else if (annotation instanceof OPTIONS) 
        parseHttpMethodAndPath("OPTIONS", ((OPTIONS) annotation).value(), false);
       else if (annotation instanceof HTTP) 
        HTTP http = (HTTP) annotation;
        parseHttpMethodAndPath(http.method(), http.path(), http.hasBody());
       else if (annotation instanceof retrofit2.http.Headers) 
        String[] headersToParse = ((retrofit2.http.Headers) annotation).value();
        if (headersToParse.length == 0) 
          throw methodError("@Headers annotation is empty.");
        
        headers = parseHeaders(headersToParse);
       else if (annotation instanceof Multipart) 
        if (isFormEncoded) 
          throw methodError("Only one encoding annotation is allowed.");
        
        isMultipart = true;
       else if (annotation instanceof FormUrlEncoded) 
        if (isMultipart) 
          throw methodError("Only one encoding annotation is allowed.");
        
        isFormEncoded = true;
      
    

这里没有什么好解释分析的,就是把我们加的方法上的注解一一处理。

在往下是处理参数注解,把所有参数注解都解析保存到了parameterHandlers里面,后面发起请求时会把这些参数放到请求里面。

到这里动态代理的invoke方法中的这行代码就分析完了:

 // 非常关键的代码1 后面展开分析
ServiceMethod<Object, Object> serviceMethod =
                (ServiceMethod<Object, Object>) loadServiceMethod(method);

由于文章太长,这里在贴下invoke方法代码

  public <T> T create(final Class<T> service) 
    ...
    return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[]  service ,
        new InvocationHandler() 

          //这里得到的是 static class Android extends Platform ...
          private final Platform platform = Platform.get();

          @Override public Object invoke(Object proxy, Method method, @Nullable Object[] args)
              throws Throwable 
            // 如果当前方法不是当前接口类里面自己定义的方法,而是Object里面的方法则
            // 直接返回默认处理 例如Object类里面的一些public定义的 wait notify notifyAll等方法
            // 要知道Object是一切类的父类
            if (method.getDeclaringClass() == Object.class) 
              return method.invoke(this, args);
            
            // 在Android里面默认是false
            if (platform.isDefaultMethod(method)) 
              return platform.invokeDefaultMethod(method, service, proxy, args);
            

            // 非常关键的代码1 后面展开分析
            ServiceMethod<Object, Object> serviceMethod =
                (ServiceMethod<Object, Object>) loadServiceMethod(method);
            OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
            // 非常关键的代码2 后面展开分析  
            return serviceMethod.adapt(okHttpCall);
          
        );
  

目前我们得到了一个ServiceMethod对象,接下来继续看下一行 

OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);

这里的 OkHttpCall 是 retrofit2 包里面的是对OKHttpCall的一个封装。

继续看下一行代码:serviceMethod.adapt(okHttpCall)

根据上面的分析,这里的callAdapter是 RxJava2CallAdapter

继续跟进:

 会根据isAsync 来最终生成一个同步 或者异步的Observable,这个isAsync是在哪赋值的呢?

这个是在构建Retrofit时,我们传入RxJava2CallAdapterFactory 时 赋值的

所以在我们的当前例子中,这个值是false,所以最终的返回值是个包含 CallExecuteObservable的

Observable。

到目前为止一切就绪,就等最终的发起请求了,请求是如何发起的?就在这行代码:

observable.xxx.subscribe(...)

subscribe()方法一执行会执行到CallExecuteObservable里面的逻辑

我们看subscribe()的源码:

 这里会执行到CallExecuteObservable d的 subscribeActual方法

这里红框的 call 是OkHttpCall(上面已经解释了),因此call.execute 会执行到OkHttpCall里面,在跟进去之前,我们来看下 如果我们不用rxjava,也就是说callAdapter 是 

ExecutorCallAdapterFactory 生产的 CallAdapter 会如何执行呢?

这里就要跳转到:

 然后得到一个ExecutorCallbackCall对象:

 这里面有同步调用和异步调用方法,看调用者调哪个了,例如:

//第二步 发起请求
Call<CommentDTO> call = mRetrofit.create(CommonServiceInterface.class).addComment(xxx,xxx);

call.execute()

我们还是看同步的情况,execute(),这样就和刚才分析的使用Rxjava的情况一样了,跟进去

 这里的rawCall才是真正的OKHttp的Call,我们看下createRawCall方法:

 call的转换还是交给了ServiceMethod,继续跟进:

 最终还是通过callFactory(OKhttpClient)来创建call,继续跟进确认:

 到此就确认完毕了,Retrofit里面的OKHttpCall这个类(名字容易误导人)只是做了一层包装,真正干活的还是OKHttp框架里面的call。

好了,我们后退两步,看看通过OKHttp里面的call执行execute后,返回的结果是如何被解析的:

就是刚才的这行代码:

    return parseResponse(call.execute());

我们看parseResponse方法:

数据转换就发生在红框标记的地方,还是serviceMethod这个大总管来处理:

 

 这里的responseConverter 在ServiceMethod 的 build方法中的

responseConverter = createResponseConverter();

中已经分析过了,在本例中就是:

  • BuiltInConverters里面的:
    • StreamingResponseBodyConverter
    • BufferingResponseBodyConverter
    • VoidResponseBodyConverter
  • 或者GsonConverterFactory里面的
    • GsonResponseBodyConverter
 这里我们就看下GsonResponseBodyConverter里面的convert方法

数据转换具体过程 就不在继续分析了。

到目前为止通过Retrofit执行一个请求的整条链路就分析完了,总结下:

  1. 构建Retrofit对象
    1. 构造callFactory ---> OKhttpClient
  2. 创建动态代理
  3. 构造ServiceMethod
    1. 准备 callAdapter
    2. 准备 responseConverter
    3. 解析 方法注解
    4. 解析 参数注解(这里面会用到数据转换器来转换参数)
  4. 构造 OkHttpCall 
  5. 构造 请求触发对象(Observable、Call等)
  6. 发起请求(调用 observable 的 subscribe 或者 call 的 execute、enqueue)
  7. 解析响应 (responseConverter转换数据)
  8. 返回给调用者

到此为止,Retrofit 核心源码分析完毕。

以上是关于Retrofit 源码分析的主要内容,如果未能解决你的问题,请参考以下文章

Retrofit源码分析&实践Retrofit CallAdapter的引入

Retrofit源码分析&实践Retrofit 多BaseUrl问题解决

Retrofit2源码分析

源码分析Retrofit请求流程

Retrofit 源码分析

Retrofit 源码分析