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 核心源码分析完毕。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
完整版:https://download.csdn.net/download/qq_27595745/89522468 【课程大纲】 1-1 什么是java 1-2 认识java语言 1-3 java平台的体系结构 1-4 java SE环境安装和配置 2-1 java程序简介 2-2 计算机中的程序 2-3 java程序 2-4 java类库组织结构和文档 2-5 java虚拟机简介 2-6 java的垃圾回收器 2-7 java上机练习 3-1 java语言基础入门 3-2 数据的分类 3-3 标识符、关键字和常量 3-4 运算符 3-5 表达式 3-6 顺序结构和选择结构 3-7 循环语句 3-8 跳转语句 3-9 MyEclipse工具介绍 3-10 java基础知识章节练习 4-1 一维数组 4-2 数组应用 4-3 多维数组 4-4 排序算法 4-5 增强for循环 4-6 数组和排序算法章节练习 5-0 抽象和封装 5-1 面向过程的设计思想 5-2 面向对象的设计思想 5-3 抽象 5-4 封装 5-5 属性 5-6 方法的定义 5-7 this关键字 5-8 javaBean 5-9 包 package 5-10 抽象和封装章节练习 6-0 继承和多态 6-1 继承 6-2 object类 6-3 多态 6-4 访问修饰符 6-5 static修饰符 6-6 final修饰符 6-7 abstract修饰符 6-8 接口 6-9 继承和多态 章节练习 7-1 面向对象的分析与设计简介 7-2 对象模型建立 7-3 类之间的关系 7-4 软件的可维护与复用设计原则 7-5 面向对象的设计与分析 章节练习 8-1 内部类与包装器 8-2 对象包装器 8-3 装箱和拆箱 8-4 练习题 9-1 常用类介绍 9-2 StringBuffer和String Builder类 9-3 Rintime类的使用 9-4 日期类简介 9-5 java程序国际化的实现 9-6 Random类和Math类 9-7 枚举 9-8 练习题 10-1 java异常处理 10-2 认识异常 10-3 使用try和catch捕获异常 10-4 使用throw和throws引发异常 10-5 finally关键字 10-6 getMessage和printStackTrace方法 10-7 异常分类 10-8 自定义异常类 10-9 练习题 11-1 Java集合框架和泛型机制 11-2 Collection接口 11-3 Set接口实现类 11-4 List接口实现类 11-5 Map接口 11-6 Collections类 11-7 泛型概述 11-8 练习题 12-1 多线程 12-2 线程的生命周期 12-3 线程的调度和优先级 12-4 线程的同步 12-5 集合类的同步问题 12-6 用Timer类调度任务 12-7 练习题 13-1 Java IO 13-2 Java IO原理 13-3 流类的结构 13-4 文件流 13-5 缓冲流 13-6 转换流 13-7 数据流 13-8 打印流 13-9 对象流 13-10 随机存取文件流 13-11 zip文件流 13-12 练习题 14-1 图形用户界面设计 14-2 事件处理机制 14-3 AWT常用组件 14-4 swing简介 14-5 可视化开发swing组件 14-6 声音的播放和处理 14-7 2D图形的绘制 14-8 练习题 15-1 反射 15-2 使用Java反射机制 15-3 反射与动态代理 15-4 练习题 16-1 Java标注 16-2 JDK内置的基本标注类型 16-3 自定义标注类型 16-4 对标注进行标注 16-5 利用反射获取标注信息 16-6 练习题 17-1 顶目实战1-单机版五子棋游戏 17-2 总体设计 17-3 代码实现 17-4 程序的运行与发布 17-5 手动生成可执行JAR文件 17-6 练习题 18-1 Java数据库编程 18-2 JDBC类和接口 18-3 JDBC操作SQL 18-4 JDBC基本示例 18-5 JDBC应用示例 18-6 练习题 19-1 。。。
完整版:https://download.csdn.net/download/qq_27595745/89522468 【课程大纲】 1-1 什么是java 1-2 认识java语言 1-3 java平台的体系结构 1-4 java SE环境安装和配置 2-1 java程序简介 2-2 计算机中的程序 2-3 java程序 2-4 java类库组织结构和文档 2-5 java虚拟机简介 2-6 java的垃圾回收器 2-7 java上机练习 3-1 java语言基础入门 3-2 数据的分类 3-3 标识符、关键字和常量 3-4 运算符 3-5 表达式 3-6 顺序结构和选择结构 3-7 循环语句 3-8 跳转语句 3-9 MyEclipse工具介绍 3-10 java基础知识章节练习 4-1 一维数组 4-2 数组应用 4-3 多维数组 4-4 排序算法 4-5 增强for循环 4-6 数组和排序算法章节练习 5-0 抽象和封装 5-1 面向过程的设计思想 5-2 面向对象的设计思想 5-3 抽象 5-4 封装 5-5 属性 5-6 方法的定义 5-7 this关键字 5-8 javaBean 5-9 包 package 5-10 抽象和封装章节练习 6-0 继承和多态 6-1 继承 6-2 object类 6-3 多态 6-4 访问修饰符 6-5 static修饰符 6-6 final修饰符 6-7 abstract修饰符 6-8 接口 6-9 继承和多态 章节练习 7-1 面向对象的分析与设计简介 7-2 对象模型建立 7-3 类之间的关系 7-4 软件的可维护与复用设计原则 7-5 面向对象的设计与分析 章节练习 8-1 内部类与包装器 8-2 对象包装器 8-3 装箱和拆箱 8-4 练习题 9-1 常用类介绍 9-2 StringBuffer和String Builder类 9-3 Rintime类的使用 9-4 日期类简介 9-5 java程序国际化的实现 9-6 Random类和Math类 9-7 枚举 9-8 练习题 10-1 java异常处理 10-2 认识异常 10-3 使用try和catch捕获异常 10-4 使用throw和throws引发异常 10-5 finally关键字 10-6 getMessage和printStackTrace方法 10-7 异常分类 10-8 自定义异常类 10-9 练习题 11-1 Java集合框架和泛型机制 11-2 Collection接口 11-3 Set接口实现类 11-4 List接口实现类 11-5 Map接口 11-6 Collections类 11-7 泛型概述 11-8 练习题 12-1 多线程 12-2 线程的生命周期 12-3 线程的调度和优先级 12-4 线程的同步 12-5 集合类的同步问题 12-6 用Timer类调度任务 12-7 练习题 13-1 Java IO 13-2 Java IO原理 13-3 流类的结构 13-4 文件流 13-5 缓冲流 13-6 转换流 13-7 数据流 13-8 打印流 13-9 对象流 13-10 随机存取文件流 13-11 zip文件流 13-12 练习题 14-1 图形用户界面设计 14-2 事件处理机制 14-3 AWT常用组件 14-4 swing简介 14-5 可视化开发swing组件 14-6 声音的播放和处理 14-7 2D图形的绘制 14-8 练习题 15-1 反射 15-2 使用Java反射机制 15-3 反射与动态代理 15-4 练习题 16-1 Java标注 16-2 JDK内置的基本标注类型 16-3 自定义标注类型 16-4 对标注进行标注 16-5 利用反射获取标注信息 16-6 练习题 17-1 顶目实战1-单机版五子棋游戏 17-2 总体设计 17-3 代码实现 17-4 程序的运行与发布 17-5 手动生成可执行JAR文件 17-6 练习题 18-1 Java数据库编程 18-2 JDBC类和接口 18-3 JDBC操作SQL 18-4 JDBC基本示例 18-5 JDBC应用示例 18-6 练习题 19-1 。。。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值