Retrofit的源码解读

687 阅读14分钟

思维导图:大致流程



一、Retrofit的简单使用

1、定义HTTP API

public interface GitHubService {
  @GET("users/{user}/repos")
  Call<List<Repo>> listRepos(@Path("user") String user);
}

2、创建Retrofit并生成API的实现

Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("https://api.github.com/")
    .build();
 
GitHubService service = retrofit.create(GitHubService.class);

3、调用API方法,生成Call

Call<List<Repo>> repos = service.listRepos("agoni_soul");


上述三个步骤就是创建并使用Retrofit的基本步骤,下面就先讲讲对这个步骤的底层源码进行讲解。


二、获得Retrofit实例

在这个获得实例的过程中,我们看看底层源码具体做了哪些工作。

Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("https://api.github.com/")
    .build();

其具体底层源码如下:

public static final class Builder {
    Builder(Platform platform) {
        this.platform = platform;
        converterFactories.add(new BuiltInConverters());
    }
    public Builder() {
        // Platform.get()方法可以用于判断当前的环境
        this(Platform.get());
    }
    public Builder baseUrl(String baseUrl) {
      checkNotNull(baseUrl, "baseUrl == null");
      HttpUrl httpUrl = HttpUrl.parse(baseUrl);
      if (httpUrl == null) {
        throw new IllegalArgumentException("Illegal URL: " + baseUrl);
      }
      return baseUrl(httpUrl);
    }
 
    public Retrofit build() {
      if (baseUrl == null) {
        throw new IllegalStateException("Base URL required.");
      }
 
      okhttp3.Call.Factory callFactory = this.callFactory;
      if (callFactory == null) {
        callFactory = new OkHttpClient();// 新建Client,留到之后newCall什么的
      }
 
      Executor callbackExecutor = this.callbackExecutor;
      if (callbackExecutor == null) {
        callbackExecutor = platform.defaultCallbackExecutor();
      }
 
      // Make a defensive copy of the adapters and add the default Call adapter.
      List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);
      adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
 
      // Make a defensive copy of the converters.
      List<Converter.Factory> converterFactories = new ArrayList<>(this.converterFactories);
 
      return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,
          callbackExecutor, validateEagerly);
    }
}

下面对这些源码进行分析

1、Builder()方法

首先调用Retrofit类的静态内部类Builder的默认无参构造方法Builder(),通过看源码可以知道,其会通过Builder(Platform.get())调用有参函数Builder(Platform platform)构造方法。从而将该platform赋值给成员变量this.platform

2、baseUrl(String baseUrl)方法

通过Builder()给成员变量platform赋值,调用baseUrl()方法来获得Builder()实例。

首先,通过checkNotNull()判断字符串baseUrl是否为空,不为空则通过HttpUrl.parse(baseUrl)是否为空来判断该Url 是否有效,而后执行baseUrl(httpUrl)来获得Builder()实例

3、build()方法

该方法用来获得Retrofit类的实例。

它内部是通过new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories, callbackExecutor, validateEagerly)来完成实例的获得。

其内部会逐步判断这些形参是否为null,为空则new一个对应的对象来获得该形参的实例。

但是对于baseUrl不会new只会抛出异常,再执行之后程序。

  • okHttp3.Call.Factory callFactory,默认是new OkHttpClient();须判断是否为null,为空则使用默认
  • Executor callbackExecutor,默认是platform.defaultCallbackExecutor();须判断是否为null,为空则使用默认
  • List<CallAdapter.Factory> adapterFactories,通过add(platform.defaultCallAdapterFactory(callbackExecutor);该方法无需判断是否为null
  • List<Converter.Factory> converterFactories,通过new ArrayList<>(this.converterFactories);该方法无须判断为null,但会通过成员变量来初始化该变量。

而对于validateEagerly,后续再进行补充。


如下面代码可以通过对okhttp3.Call.Factory 进行直接赋值,对List<Converter.Factory>进行赋值。

retrofit2.Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("https://gank.io/api/")
        .addConverterFactory(GsonConverterFactory.create(new GsonBuilder().create()))
        .client(RequestDataByRetrofit.getOkHttpClientInstance())
        .build();

addConverterFactory(GsonConverterFactory.create(new GsonBuilder().create()))是对List<Converter.Factory>进行赋值

client(RequestDataByRetrofit.getOkHttpClientInstance())是对okhttp3.Call.Factory进行赋值。


需要注意的地方:

除了builder模式以外,还有两个地方需要关注下,一个是Platform.get()方法。它是通过Class.forName获取类名的方式,来判断当前环境是否在Android中,这在之后或得默认的CallAdapterFactory时候将会用到。

另一个是在build()中创建OkHttpClient。


三、retrofit.create()

1、create()的底层源码

public <T> T create(final Class<T> service) {
  Utils.validateServiceInterface(service);
  if (validateEagerly) {
    eagerlyValidateMethods(service);
  }
  // 动态代理
  return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
      new InvocationHandler() {
        // platform 可以分辨出你是在android,还是java8,又或者别的
        private final Platform platform = Platform.get();
        @Override public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
          // If the method is a method from Object then defer to normal invocation.
          // 这里的invoke,Object方法都走这里,比如equals、toString、hashCode什么的
          if (method.getDeclaringClass() == Object.class) {
            return method.invoke(this, args);
          }
          // java8默认方法,1.8的新特性
          if (platform.isDefaultMethod(method)) {
            return platform.invokeDefaultMethod(method, service, proxy, args);
          }
          // 这里是核心代码了
          ServiceMethod<Object, Object> serviceMethod =
              (ServiceMethod<Object, Object>) loadServiceMethod(method);
          OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
          return serviceMethod.callAdapter.adapt(okHttpCall);
        }
      });
}

可以看出创建API使用了动态代理,根据接口动态生成的代理类,将接口的都转发给了负责连接代理类和委托类的InvocationHandler实例,接口方法也都是通过其invoke()方法来处理。

invoke()方法中,首先会通过Platform.get()方法判断出当前代码的执行环境,之后会先把ObjectJava8默认方法进行一个处理,也是在进行后续处理之前。

其中关键代码是最后三句。

2、创建ServiceMethod

ServiceMethod<?, ?> loadServiceMethod(Method method) {
  // 从缓存里面取出,如果有的话,直接返回好了
  ServiceMethod<?, ?> result = serviceMethodCache.get(method);
  if (result != null) return result;
  synchronized (serviceMethodCache) {
    result = serviceMethodCache.get(method);
    if (result == null) {
      // 为null的话,解析方法的注解和返回类型、参数的注解和参数类型,新建一个ServiceMethod
      result = new ServiceMethod.Builder<>(this, method).build();// ->
      // 新建的ServiceMethod加到缓存列表里面
      serviceMethodCache.put(method, result);
    }
  }
  return result;
}

首先会尝试根据方法从缓冲中取出ServiceMethod实例

缓冲中没有实例,则通过对ServiceMethoCacheSynchronized锁再进行一次尝试,若仍然为空则创建ServiceMethod。

ServiceMethod创建与Retrofit类似,都是使用builder模式(建造者模式)。ServiceMethod创建的实例过程都放在了最后的build()方法中。

public ServiceMethod build() {
  //获得CallAdapter的实现,一般为ExecutorCallAdapterFactory.get来实现
  callAdapter = createCallAdapter();
  responseType = callAdapter.responseType();
  if (responseType == Response.class || responseType == okhttp3.Response.class) {
    throw methodError("'"
        + Utils.getRawType(responseType).getName()
        + "' is not a valid response body type. Did you mean ResponseBody?");
  }
  //响应的转换工厂,如GsonConverterFactory
  responseConverter = createResponseConverter();
  for (Annotation annotation : methodAnnotations) {
    //真正解析方法注解的地方
    parseMethodAnnotation(annotation);
  }
  if (httpMethod == null) {
    throw methodError("HTTP method annotation is required (e.g., @GET, @POST, etc.).");
  }
  if (!hasBody) {// POST方法需要有body或者表单
    if (isMultipart) {
      throw methodError(
          "Multipart can only be specified on HTTP methods with request body (e.g., @POST).");
    }
    if (isFormEncoded) {
      throw methodError("FormUrlEncoded can only be specified on HTTP methods with "
          + "request body (e.g., @POST).");
    }
  }
  // 上面是请求方法,下面是请求参数
  int parameterCount = parameterAnnotationsArray.length;
  // ParameterHandler的实现类有很多,包括了各种参数,@Field、@Query等
  parameterHandlers = new ParameterHandler<?>[parameterCount];
  for (int p = 0; p < parameterCount; p++) {
    Type parameterType = parameterTypes[p];// 参数类型
    // 和之前一样的泛型、通配符检查
    if (Utils.hasUnresolvableType(parameterType)) {
      throw parameterError(p, "Parameter type must not include a type variable or wildcard: %s",
          parameterType);
    }
    Annotation[] parameterAnnotations = parameterAnnotationsArray[p];// 参数的注解集合
    if (parameterAnnotations == null) {
      throw parameterError(p, "No Retrofit annotation found.");
    }
    // 生成了对应的参数注解ParameterHandler实例
    parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);
  }
  // 对方法的一些检测
  ...
 
  return new ServiceMethod<>(this);
}

在build()方法中

  • 首先通过createCallAdapter()(对应于Builder.build()adapterFactories)获得callAdapter对象,并调用responseType()方法,并对其进行相应的判断。
  • 再通过createResponseConverter()(对应于Builder.build()callFacotory)来获得responseConverter对象,并通过foreach循环解析方法注解
  • 对注解的HTTPMethod进行检查,需要表明Http请求方法注解的类型,如@GET@POST等等。
  • 在对Http中的hasBody判断,因为@POST,需要有body部分,并对其中的body的标记类注解MultipartFormEncoded进行判断。
  • 完成上述操作后再对请求参数进行判断(说简单点即Url),该部分主要是完成对参数型注解进行判断。

可以看到在build()方法中,对CallAdapterConverter进行了创建,这里跟踪之后将会回到Retrofit类中,在其中将会获取对应列表中的第一个!null对象,之后将会对API的方法和参数注解进行解析。

3、parseMethodAnnotation(annotation)源码

该方法的功能和其名字一样,对Http请求方法注解进行解析。

/**
 * 解析方法注解
 * 通过判断注解类型来解析
 * @param annotation
 */
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);
  } 
  // 其他的一些方法注解的解析
  ...
}
 
private void parseHttpMethodAndPath(String httpMethod, String value, boolean hasBody) {
  if (this.httpMethod != null) {// 已经赋值过了
    throw methodError("Only one HTTP method is allowed. Found: %s and %s.",
        this.httpMethod, httpMethod);
  }
  this.httpMethod = httpMethod;
  this.hasBody = hasBody;
  // value为设置注解方法时候,设置的值,官方例子中的users/{user}/repos or user
  if (value.isEmpty()) {
    return;
  }
  // 查询条件的一些判断
    ...
  this.relativeUrl = value;
  this.relativeUrlParamNames = parsePathParameters(value);
}

Retrofit支持八种HTTP请求方法注解,分别是:GET、POST、PUT、DELETE、HEAD、PATCH、OPTIONS、HTTP

parseMethodAnnotation()方法中就是对这些请求方法注解进行检验,先通过instanceOf判断出注解的类型,之后调用parseHttpMethodAndPath()方法解析注解参数值,并设置HTTPMethodrelativeUrlrelativeUrlParamNames等属性,,并对之前的HttpMethod不为null时抛出异常,并将新值赋值给它。


在上面说了API中方法注解的解析,现在来看看方法参数注解的解析,这里通过调用parseParameterAnnotation()方法生成ParameterHandler实例来实现的,代码比较多,这里挑选@Query来看看。

else if (annotation instanceof Query) {
Query query = (Query) annotation;
String name = query.value();
boolean encoded = query.encoded();
 
Class<?> rawParameterType = Utils.getRawType(type);// 返回基础的类
gotQuery = true;
// 可以迭代,Collection
if (Iterable.class.isAssignableFrom(rawParameterType)) {
  if (!(type instanceof ParameterizedType)) {
    throw parameterError(p, rawParameterType.getSimpleName()
        + " must include generic type (e.g., "
        + rawParameterType.getSimpleName()
        + "<String>)");
  }
  ParameterizedType parameterizedType = (ParameterizedType) type;
  Type iterableType = Utils.getParameterUpperBound(0, parameterizedType);// 返回基本类型
  Converter<?, String> converter =
      retrofit.stringConverter(iterableType, annotations);
  return new ParameterHandler.Query<>(name, converter, encoded).iterable();
} else if (rawParameterType.isArray()) {// Array
  //如果是基本类型,自动装箱
  Class<?> arrayComponentType = boxIfPrimitive(rawParameterType.getComponentType());
  Converter<?, String> converter =
      retrofit.stringConverter(arrayComponentType, annotations);
  return new ParameterHandler.Query<>(name, converter, encoded).array();
} else {// Other
  Converter<?, String> converter =
      retrofit.stringConverter(type, annotations);
  return new ParameterHandler.Query<>(name, converter, encoded);
}

在@Query中,将分成Collectionarrayother三种情况处理参数,之后根据这些参数,调用ParameterHandler中的Query静态类,创建出一个ParameterHandler实例。这样循环知道解析了所有的参数注解,组合成为全局变量parameterHandlers,之后构建网络请求时会用到。


四、OkHttpCall

ServiceMethod创建完成之后,我们来看看下一行代码的OkHttpCall类,里面的包含了请求的执行和响应处理,看看异步请求的源码

OkHttpCall(ServiceMethod<T, ?> serviceMethod, Object[] args) {
  this.serviceMethod = serviceMethod;
  this.args = args;
}
 
@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 {
      call = rawCall = createRawCall();// 创建OkHttp3.Call
    } catch (Throwable t) {
      failure = creationFailure = t;
    }
  }
}
 
//回调onFailure()方法
if (failure != null) {
  callback.onFailure(this, failure);
  return;
}
 
if (canceled) {
  call.cancel();
}

call.enqueue(new okhttp3.Callback() {
  @Override 
  public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse)
      throws IOException {
    Response<T> response;
    try {
      response = parseResponse(rawResponse);
    } catch (Throwable e) {
      callFailure(e);
      return;
    }
    callSuccess(response);
  }
 
  @Override 
  public void onFailure(okhttp3.Call call, IOException e) {
    try {
      callback.onFailure(OkHttpCall.this, e);
    } catch (Throwable t) {
      t.printStackTrace();
    }
  }
 
  private void callFailure(Throwable e) {
    try {
      callback.onFailure(OkHttpCall.this, e);
    } catch (Throwable t) {
      t.printStackTrace();
    }
  }
 
  private void callSuccess(Response<T> response) {
    try {
      callback.onResponse(OkHttpCall.this, response);
    } catch (Throwable t) {
      t.printStackTrace();
    }
  }
});
}
 
private okhttp3.Call createRawCall() throws IOException {
  //根据ParameterHandler组装Request.Builder,生成Request
  Request request = serviceMethod.toRequest(args);
  //Retrofit中创建的new OkHttpClient().newCall(request)
  okhttp3.Call call = serviceMethod.callFactory.newCall(request);
  ...
  return call;
}
  • 首先在构造方法中传入之前新建的serviceMethod和动态代理invoke()方法传递的args参数。
  • 异步方法enqueue(),通过synchronized锁来保证只有一个call对象一个failure对象,如都为空则通过调用createRawCall()方法,跟着其将完成两件事情
  • 第一件是:调用serviceMethod.toRequest()方法,创建一个Request对象,这个Request对象就是就是根据之前提到的方法参数注解的集合ParameterHandlers创建的。
  • 第二件是创建一个okhttp3.Call对象,在Okhttp中创建这个对象的方法是newCall(),那么callFactory参数是不是就是OkHttpClient呢?跟踪程序发现,的确是这样,它的创建出现在Retrofit.Builder.build()方法中,而参数就是使用刚刚创建request对象,构成okhttp3.Call并返回
  • 注意在call.enqueue()方法中,我们通过重写onResponse()onFailure()方法来获取网络请求成功或失败的数据


五、CallAdapter

现在来看看enqueue传入的参数callback,这个参数并不是用户在使用时传入的那个Callback对象。

1、Android类

那么它是从哪里来的呢?不知道你还记不记得之前在Retrofit.Builder.build()方法中提到过一句代码Platform.get()。在不使用addCallAdapterFactory的情况下,将会使用Platform的一种内部类,在Android环境下将会使用到Android类(这其实是一个策略模式

static class Android extends Platform {
  @Override 
  public Executor defaultCallbackExecutor() {
    return new MainThreadExecutor();
  }
  @Override 
  CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {
    return new ExecutorCallAdapterFactory(callbackExecutor);
  }
  static class MainThreadExecutor implements Executor {
    // Looper.getMainLooper()就是为嘛响应会在主线程的原因
    private final Handler handler = new Handler(Looper.getMainLooper());
    @Override public void execute(Runnable r) {
      handler.post(r);
    }
  }
}

注意该Android类继承Platform类,并且是static修饰的内部类


还记得在retrofit.Builder.build()方法中,有如下关键代码

callFactory = new OkHttpClient();
callbackExecutor = platform.defaultCallbackExecutor();
adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));

结合Android类中的代码可以看到,其最后生成了ExecutorCallAdapterFactory类。虽然看到了CallAdapter.Factory,但是到底是哪里执行了enqueue()方法呢?

2、返回值为CallAdapter的ExecutorCallAdapterFactory.get()方法

现在再看看retrofit.create()的最后一句代码serviceMethod.callAdapter.adapte(okHttpCall)

这里的callAdapter不使用addCallAdapterFactory的Android环境下,就是上面我们说到new ExecutorCallAdapterFactoryget()方法返回的对象

@Override
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
  if (getRawType(returnType) != Call.class) {
    return null;
  }
  final Type responseType = Utils.getCallResponseType(returnType);
  return new CallAdapter<Object, Call<?>>() {
    @Override 
    public Type responseType() {
      return responseType;
    }
    @Override 
    //Retrofit动态代理serviceMethod.callAdapter.adapt(okHttpCall);调用这个方法
    public Call<Object> adapt(Call<Object> call) {
      return new ExecutorCallbackCall<>(callbackExecutor, call);
    }
  };
}

3、ExecutorCallbackCall()对象

responseType()方法返回的对象之后会到Converter中用到,不过接下来先继续看看其调用adapter()方法生成的ExecutorCallbackCall对象。

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);
        }
      });
    }
  });
}

这里的参数callback才是用户输入的回调对象,而其中的delegate就是之前的okhttpCall。所以delegate.enqueue()的执行是通过用户直接调用,调用之后会进入OkhttpCall.enqueue()的执行,然后再回调用户执行器callbackExecutor执行返回用户程序

4、补充讲解RxJava2CallAdapter

顺便再来看看常用的RxJava2CallAdapter,这里直接从RxJava2CallAdapter.adapter()方法开始

@Override 
public Object adapt(Call<R> 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);
  }
  ...
  return observable;
}

adapter最终创建了Observable,在这里我们分析开头的两步:

  • 分异步和同步请求创建responseObservable
  • 根据返回的类型创建observable

这里以异步为例,看看CallEnqueueObservable类

final class CallEnqueueObservable<T> extends Observable<Response<T>> {
  private final Call<T> originalCall;
 
  CallEnqueueObservable(Call<T> originalCall) {
    this.originalCall = originalCall;
  }
 
  @Override 
  protected void subscribeActual(Observer<? super Response<T>> observer) {
    // Since Call is a one-shot type, clone it for each new observer.
    Call<T> call = originalCall.clone();
    CallCallback<T> callback = new CallCallback<>(call, observer);
    observer.onSubscribe(callback);
    call.enqueue(callback);// 这里执行了enqueue
  }
 
  private static final class CallCallback<T> implements Disposable, Callback<T> {
    private final Call<?> call;
    private final Observer<? super Response<T>> observer;
    boolean terminated = false;
 
    CallCallback(Call<?> call, Observer<? super Response<T>> observer) {
      this.call = call;
      this.observer = observer;
    }
 
    @Override 
    public void onResponse(Call<T> call, Response<T> response) {
      if (call.isCanceled()) return;
 
      try {
        observer.onNext(response);
 
        if (!call.isCanceled()) {
          terminated = true;
          observer.onComplete();
        }
      } catch (Throwable t) {
        ...
      }
    }
 
    @Override 
    public void onFailure(Call<T> call, Throwable t) {
      if (call.isCanceled()) return;
 
      try {
        observer.onError(t);
      } catch (Throwable inner) {
        Exceptions.throwIfFatal(inner);
        RxJavaPlugins.onError(new CompositeException(t, inner));
      }
    }
 
    ...
  }
}

在subscribeActual()方法中,主要做了三件事情:

  • clone了原有的call,因为OkHttp.Call只能使用一次
  • 设置了onSubscribe,可用来解除订阅
  • 执行了enqueue请求


再看看第二步,这里以BodyObservable为例:

 final class BodyObservable<T> extends Observable<T> {
  private final Observable<Response<T>> upstream;
 
  BodyObservable(Observable<Response<T>> upstream) {
    this.upstream = upstream;
  }
 
  @Override 
  protected void subscribeActual(Observer<? super T> observer) {
    upstream.subscribe(new BodyObserver<T>(observer));
  }
 
  private static class BodyObserver<R> implements Observer<Response<R>> {
    private final Observer<? super R> observer;
    private boolean terminated;
 
    BodyObserver(Observer<? super R> observer) {
      this.observer = observer;
    }
 
    @Override 
    public void onSubscribe(Disposable disposable) {
      observer.onSubscribe(disposable);
    }
 
    @Override 
    public void onNext(Response<R> response) {
      if (response.isSuccessful()) {
        observer.onNext(response.body());
      } else {
        ...
          observer.onError(t);
        ...
      }
    }
 
    @Override 
    public void onComplete() {
      if (!terminated) {
        observer.onComplete();
      }
    }
 
    @Override 
    public void onError(Throwable throwable) {
      if (!terminated) {
        observer.onError(throwable);
      } 
      ...
    }
  }
}

代码中的subscribeActual()方法在subscribe()之后执行,自然responseObservable()就订阅了BodyObserver,所以上面CallEnqueueObservable中的CallCallback.onResponse()内,调用observer.onNext()也就是BodyObserver.onNext(),最后刚开始的观察者就收到了response.body()

(该部分具体在RxJava底层源码中有讲解,不懂可以搜索下RxJava底层源码实现


六、Converter

现在回到OkhttpCall.enqueue()方法中,在其中还有一句重要的代码没有看,那就是response=parseResponse(rawResponse);

1、parseResponse()方法

接下来具体看看该代码的功能:

Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException
  ResponseBody rawBody = rawResponse.body();
  // Remove the body's' source (the only stateful object) so we can pass th
  rawResponse = rawResponse.newBuilder()
      .body(new NoContentResponseBody(rawBody.contentType(), rawBody.conte
      .build();
  ...
  ExceptionCatchingRequestBody catchingBody = new ExceptionCatchingRequestBody(rawBody);
  try {
    T body = serviceMethod.toResponse(catchingBody);// 解析body,比如Gson解析
    return Response.success(body, rawResponse);
  } catch (RuntimeException e) {
    // If the underlying source threw an exception, propagate that rather 
    // a runtime exception.
    catchingBody.throwIfCaught();
    throw e;
  }
}
 
### ServiceMethod
R toResponse(ResponseBody body) throws IOException {
  return responseConverter.convert(body);
}

2、GsonConverterFactory()方法

可以看出parseResponse最终调用了Converter.convert()方法。这里以常用的GsonConverterFactory()为例:

 
# GsonConverterFactory
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
    Retrofit retrofit) {
  TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
  return new GsonResponseBodyConverter<>(gson, adapter);
}
 
# GsonResponseBodyConverter
final class GsonResponseBodyConverter<T> implements Converter<ResponseBody, T> {
  private final Gson gson;
  private final TypeAdapter<T> adapter;
  GsonResponseBodyConverter(Gson gson, TypeAdapter<T> adapter) {
    this.gson = gson;
    this.adapter = adapter;
  }
  @Override 
  public T convert(ResponseBody value) throws IOException {
    JsonReader jsonReader = gson.newJsonReader(value.charStream());
    try {
      return adapter.read(jsonReader);
    } finally {
      value.close();
    }
  }
}

responseBodyConverter()方法中用到的type参数就是之前在CallAdapter中提到的responseType()方法的返回值,生成adapter()方法,用到convert()方法使用。OkhttpCall在这之后的代码就比较简单了,通过回调将转换后的响应数据发送出去即可。


总结

本文分析了Retrofit的执行流程,其中包含了RetrofitServiceMethodOkHttpCallCallAdapterConverter等方面。Retrofit的代码相对比较少,也比较容易理解,不过确实很好的架构实例。


文中绝大多数的文字和代码来源:最全的Retrofit底层源码,清晰易懂(源码到原理实现)