Retrofit分别用了哪些设计模式

361 阅读13分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第35天,点击查看活动详情

1.简介:

  • Retrofit是一个RESTful的HTTP网络请求框架的封装
  • 网络请求的工作本质上是由OkHttp完成的,而Retrofit仅负责网络请求接口的封装
  • APP通过Retrofit请求网络,实际上是使用Retrofit接口层封装请求参数,请求头,URL等信息,最后是由OkHttp完成后续的请求操作
  • 在服务端返回数据后,OkHttp将原始的结果交给Retrofit,Retrofit根据用户需求对结果进行解析。
  • 优点:
    • 支持同步、异步;支持多种数据的解析;支持RxJava
    • 通过注解配置网络请求参数,采用大量设计模式简化使用
    • 功能模块高度封装,解耦彻底

2.具体使用

这里不进行详细描述

3.源码分析

  • Retrofit用到的设计模式:建造者模式,工厂模式,外观模式,代理模式,单例模式,策略模式,装饰模式,适配器模式

image.png

1.创建Retrofit实例

通过内部类Builder类建立了一个Retrofit实例(建造者模式),具体创建过程是配置了:

  • 平台类型对象(Platform-Android)
    • Retrofit创建实例后的下一步是调用了Builder,从Builder()看起
public Builder() {
    //这里调用了Builder的有参的构造方法并且传入了Platform().get()参数
    this(Platform.get());
}

class Platform {
  //这里是Platform.get()返回的内容
  private static final Platform PLATFORM = findPlatform();

  static Platform get() {
    return PLATFORM;
  }
   ...
}

//这里就确定了具体的平台,同时也可以得知Retrofit支持Android、Java、IOS三个平台
private static Platform findPlatform() {
    try {
        Class.forName("android.os.Build");
        if (Build.VERSION.SDK_INT != 0) {
            //这里表示如果是Android平台就返回一个Android对象,
            //那么这个Android对象又做了什么,咱们往下看
            return new Android();
        }
    } catch (ClassNotFoundException ignored) {
    }
    try {
        Class.forName("java.util.Optional");
        return new Java8();
    } catch (ClassNotFoundException ignored) {
    }
    try {
        Class.forName("org.robovm.apple.foundation.NSObject");
        return new IOS();
    } catch (ClassNotFoundException ignored) {
    }
    return new Platform();
}

//由源码可知Android继承自Platform
static class Android extends Platform {
    @Override public Executor defaultCallbackExecutor() {
        //返回默认的方法执行器,作用就是线程切换(子线程→主线程),并在主线程执行回调方法
        return new MainThreadExecutor();
    }

    @Override CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {
        //创建并返回默认的网络请求适配器工厂
        //这个工厂产生的adapter会使得call在异步调用时在指定的Executor上执行
        //Retrofit上提供了四种CallAdapterFactory: ExecutorCallAdapterFactory(默认)、
        //GuavaCallAdapterFactory、Java8CallAdapterFactory、RxJavaCallAdapterFactory
        return new ExecutorCallAdapterFactory(callbackExecutor);
    }

    static class MainThreadExecutor implements Executor {
        //获取与Android主线程绑定的Handler
        private final Handler handler = new Handler(Looper.getMainLooper());

        @Override public void execute(Runnable r) {
            //这里任务就是在主线程处理数据
            handler.post(r);3
        }
    }
}

//切换线程的流程::
//1.回调ExecutorCallAdapterFactory生成ExecutorCallbackCall对象
//2.通过调用ExecutorCallbackCall.enqueue(callback)从而调用MainThreadExecutor.execute()进行线程切换


//再回到Builder的有参构造函数中
Builder(Platform platform) {
    //这里接接收了返回的Android平台
    this.platform = platform;
    //添加了一个内置转换器
    converterFactories.add(new BuiltInConverters());
    //BuiltInConverters是一个内置的数据转换器,继承自Converter.Factory
}
  • 网络请求的url地址(baseUrl)
    • 从baseUrl源码开始看起
public Builder baseUrl(String baseUrl) {
    checkNotNull(baseUrl, "baseUrl == null");
    //将传入的String类型的url转换成适合OkHttp的Url类型
    HttpUrl httpUrl = HttpUrl.parse(baseUrl);
    if (httpUrl == null) {
        throw new IllegalArgumentException("Illegal URL: " + baseUrl);
    }
    
    //url转换完毕后会通过baseUrl返回,那么这个baseUrl又做了什么,继续往下看
    return baseUrl(httpUrl);
}

//这里主要是做了格式验证
public Builder baseUrl(HttpUrl baseUrl) {
    checkNotNull(baseUrl, "baseUrl == null");
    //这里把url分割成了几个碎片
    List<String> pathSegments = baseUrl.pathSegments();
    
    //这里判断传入的url的最后一个字符是否是【/】,如果不是则抛出异常
    if (!"".equals(pathSegments.get(pathSegments.size() - 1))) {
        throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl);
    }
    this.baseUrl = baseUrl;
    //传入的url没有异常,最终返回baseUrl对象
    return this;
}
  • 网络请求工厂(callFactory)默认使用OkHttpCall(工厂方法模式)
    • OkHttpCall是Retrofit中默认的Call,可以被转换成适合被不同平台来调用的网络请求执行器形式
    • 在Retrofit中提供了四种CallAdapterFactory: ExecutorCallAdapterFactory(默认)、GuavaCallAdapterFactory、Java8CallAdapterFactory、RxJavaCallAdapterFactory
  • 网络请求适配器工厂的集合(adapterFactories),默认是ExecutorCallAdapterFactory
    • addCallAdapterFactory(RxJava2CallAdapterFactory.create())
//这里默认的是ExecutorCallAdapterFactory,在Builder()中的
//MainThreadExecutor()执行了platform.defaultCallAdapterFactory)
//与RxJava一起使用时添加的则是RxJava2CallAdapterFactory.create())
public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
    adapterFactories.add(checkNotNull(factory, "factory == null"));
    return this;
}

public static RxJava2CallAdapterFactory create() {
    return new RxJava2CallAdapterFactory(null);
}

private RxJava2CallAdapterFactory(Scheduler scheduler) {
    this.scheduler = scheduler;
}
  • 数据转换器工厂的集合(convertFactories),本质是配置了数据转换器工厂
    • addConverterFactory(GsonConverterFactory.create()),GsonConverterFactory.create()创建的是一个含有gson实例的GsonConverterFactory最后再返回给addConverterFactory
//这里的主要作用就是将创建的GsonConverterFactory添加到converterFactories数组中
public Builder addConverterFactory(Converter.Factory factory) {
    converterFactories.add(checkNotNull(factory, "factory == null"));
    return this;
}

public static GsonConverterFactory create() {
    //创建一个Gson实例
    return create(new Gson());
}

public static GsonConverterFactory create(Gson gson) {
    //创建一个含有gson的Gson数据转换工厂
    return new GsonConverterFactory(gson);
}

private GsonConverterFactory(Gson gson) {
    if (gson == null) throw new NullPointerException("gson == null");
    this.gson = gson;
}
  • 回调方法执行器(callbackExecutor),默认回调方法执行器的作用是:切换线程(子线程-主线程)
    • 在确定平台时有所表示,默认defaultCallbackExecutor,执行的任务就是子线程切换到主线程
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 {
        private final Handler handler = new Handler(Looper.getMainLooper());

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

2.创建网络请求接口的实例(通过解析注解配置网络请求参数)

Retrofit采用外观模式统一调用创建网络请求接口实例和网络请求参数配置的方法,过程如下

  • 动态创建网络请求接口实例(代理模式-动态代理#InnavationHandler对象#invoke())
    • 创建网络请求接口的实例的主要代码是retrofit.create(),这行代码采用了外观模式,在create()方法中通过动态代理的方式创建了请求接口的实例
public <T> T create(final Class<T> service) {
    Utils.validateServiceInterface(service);
    if (validateEagerly) {
        //判断是否需要提前验证
		//主要作用是解析接口中的每个方法的注解并得到一个serviceMethod对象
        //然后以method为键将serviceMethod存到LinkedHashMap中,类似延迟加载
        eagerlyValidateMethods(service);	//关注点1
    }

    //通过动态生成的代理类,调用interfaces接口的方法实际上是由InvocationHandler对象的invoke完成的
    return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
                                      new InvocationHandler() {
                                          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.
                                              if (method.getDeclaringClass() == Object.class) {
                                                  return method.invoke(this, args);
                                              }
                                              if (platform.isDefaultMethod(method)) {
                                                  return platform.invokeDefaultMethod(method, service, proxy, args);
                                              }
                                              ServiceMethod serviceMethod = loadServiceMethod(method);
                                              OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
                                              return serviceMethod.callAdapter.adapt(okHttpCall);
                                          }
                                      });
}

private void eagerlyValidateMethods(Class<?> service) {
    Platform platform = Platform.get();
    //解析注解并得到method
    for (Method method : service.getDeclaredMethods()) {
        if (!platform.isDefaultMethod(method)) {
            loadServiceMethod(method);
        }
    }
}

ServiceMethod loadServiceMethod(Method method) {
    ServiceMethod result;
    synchronized (serviceMethodCache) {
		//这里得到了serviceMethod对象
        result = serviceMethodCache.get(method);
        if (result == null) {
            result = new ServiceMethod.Builder(this, method).build();
            //method为键,serviceMethod为值存入最初定义的LinkedHashMap集合中
            //serviceMethodCache的作用是存储网络请求的配置,如网络请求的方法、基地址、数据转换器,网络请求工厂,网络请求适配器等
            serviceMethodCache.put(method, result);
        }
    }
    return result;
}
  • 创建serviceMethod对象(建造者模式&单例模式(缓存机制))
    • 动态创建网络请求接口的实例中知道调用interfaces接口的方法实际上是由InvocationHandler中的invoke()来完成的,在invoke()方法中创建了serviceMethod对象
new InvocationHandler() {
    private final Platform platform = Platform.get();

    @Override public Object invoke(Object proxy, Method method, Object... args)
        throws Throwable {
       	...
        
        //创建了ServiceMethod对象
        ServiceMethod serviceMethod = loadServiceMethod(method);
        
		//创建了OkHttpCall对象
        OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
        return serviceMethod.callAdapter.adapt(okHttpCall);
    }
}

//这里有一个创建实例的缓存机制:采用单例模式实现一个ServiceMethod对象并且对应网络请求接口里的一个方法
//每一个ServiceMethod对象对应网络请求接口里的一个方法
ServiceMethod loadServiceMethod(Method method) {
    ServiceMethod result;
    //设置线程同步锁
    synchronized (serviceMethodCache) {
        //这里采用了单例模式获取ServiceMethod对象,先判断是否有这个缓存
        result = serviceMethodCache.get(method);
        
        //如果没有则进行创建
        if (result == null) {
            //这里的创建ServiceMethod对象采用了建造者模式
            result = new ServiceMethod.Builder(this, method).build();
            serviceMethodCache.put(method, result);
        }
    }
    return result;
}

//ServiceMethod#Builder
public Builder(Retrofit retrofit, Method method) {
    this.retrofit = retrofit;
    this.method = method;
    //获取网络请求接口里的注释
    this.methodAnnotations = method.getAnnotations();
    //获取参数类型
    this.parameterTypes = method.getGenericParameterTypes();
    //获取网络请求接口离得注解内容
    this.parameterAnnotationsArray = method.getParameterAnnotations();
}

//ServiceMethod#build
//控制ServiceMethod对象的生成流程
public ServiceMethod build() {
    //根据网络请求接口方法的返回值和注解类型获取网络请求适配器	—关注点1
    callAdapter = createCallAdapter();
    //获取网络适配器返回的数据类型
    responseType = callAdapter.responseType();
    
   	...
    //获取对应的数据转换器    
    //构造Http请求时,传递的参数都是String类型
    //Retrofit类提供的convert把传递的参数都转换成String
    //其余类型的参数都是由Convert.Factory转换的例如@Body,@Part等	—关注点2
    responseConverter = createResponseConverter();

    for (Annotation annotation : methodAnnotations) {
        //解析网络请求接口中的方法注解获取网络请求的方法(GET、POST等)
        parseMethodAnnotation(annotation);
        //处理调用的方法是parseHttpMethodAndPath()
    }

   ...

    //获取当前方法参数数量
    int parameterCount = parameterAnnotationsArray.length;
    //给每一个参数创建一个ParameterHandler
    parameterHandlers = new ParameterHandler<?>[parameterCount];
    for (int p = 0; p < parameterCount; p++) {
        //获取每一个参数的注解类型(Body、Part、Field等)
        Type parameterType = parameterTypes[p];
       	...
        Annotation[] parameterAnnotations = parameterAnnotationsArray[p];
        if (parameterAnnotations == null) {
            throw parameterError(p, "No Retrofit annotation found.");
        }

        parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);
    }

    ...
        return new ServiceMethod<>(this);
}

//关注点1:分析createCallAdapter()查看网络请求适配器是怎么获取的
private CallAdapter<?> createCallAdapter() {
    //获取网络请求接口方法的返回值类型
    Type returnType = method.getGenericReturnType();
    ...
    //获取网络请求的注解
    Annotation[] annotations = method.getAnnotations();
    try {
        //根据网络请求接口方法的返回值和注解通过retrofit获取网络请求适配器
        return retrofit.callAdapter(returnType, annotations);
    } catch (RuntimeException e) { // Wide exception range because factories are user code.
        ...
    }
}

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

//创建并返回CallAdapter
public CallAdapter<?> nextCallAdapter(CallAdapter.Factory skipPast, Type returnType,
                                      Annotation[] annotations) {
	...
        
    int start = adapterFactories.indexOf(skipPast) + 1;
    //遍历CallAdapter.Factory集合寻找合适的工厂,这个工厂在创建Retrofit实例时就已经添加,如果没有则抛出异常
    for (int i = start, count = adapterFactories.size(); i < count; i++) {
        CallAdapter<?> adapter = adapterFactories.get(i).get(returnType, annotations, this);
        if (adapter != null) {
            return adapter;
        }
    }
    ...
}

//关注点2:createResponseConverter
private Converter<ResponseBody, T> createResponseConverter() {
    Annotation[] annotations = method.getAnnotations();
    try {
        return retrofit.responseBodyConverter(responseType, annotations);
    } catch (RuntimeException e) { // Wide exception range because factories are user code.
        throw methodError(e, "Unable to create converter for %s", responseType);
    }
}

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

public <T> Converter<ResponseBody, T> nextResponseBodyConverter(Converter.Factory skipPast,
                                                                Type type, Annotation[] annotations) {
    ...
        
    int start = converterFactories.indexOf(skipPast) + 1;
    //遍历Converter.Factory查找合适的合适的工厂,这个工厂在创建Retrofit实例时已经添加,如果没有则抛出异常
    for (int i = start, count = converterFactories.size(); i < count; i++) {
        //因为在创建Retrofit实例时添加的是gson因此获取到的converter是GsonResponseBodyConverter
        Converter<ResponseBody, ?> converter =
            converterFactories.get(i).responseBodyConverter(type, annotations, this);
        if (converter != null) {
            //noinspection unchecked
            return (Converter<ResponseBody, T>) converter;
        }
    }
	...
}

//responseBodyConverter
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
                                                        Retrofit retrofit) {
    TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
    // 根据目标类型,利用 Gson#getAdapter 获取相应的 adapter
    return new GsonResponseBodyConverter<>(gson, adapter);
}

// 做数据转换时调用 Gson 的 API 即可。
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();
    }
  }
}
  • 对serviceMethod对象进行网络请求参数配置:通过解析网络请求接口方法的参数、返回值和注解类型,从Retrofit对象中获取对应的网络请求url地址,网络请求执行器,网络请求适配器,数据转换器。(策略模式)
new InvocationHandler() {
    private final Platform platform = Platform.get();

    @Override public Object invoke(Object proxy, Method method, Object... args)
        throws Throwable {
       	...
        
       //这里返回值得类型是由addCallAdapterFactory决定的
       //如果设置了RxJava2CallAdapterFactory返回值的类型就是Observable<>,没有设置则是默认Call<>
        return serviceMethod.callAdapter.adapt(okHttpCall);
    }
}

//adapt详解
public <R> Call<R> adapt(Call<R> call) {
    return new ExecutorCallbackCall<>(callbackExecutor, call);  
}

ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) {
    // 把上面创建并配置好参数的OkhttpCall对象交给静态代理delegate
    // 静态代理和动态代理都属于代理模式
    // 静态代理作用:代理执行被代理者的方法,且可在要执行的方法前后加入自己的动作,进行对系统功能的拓展
    this.delegate = delegate;	
    
    // 传入上面定义的回调方法执行器
    // 用于进行线程切换	
    this.callbackExecutor = callbackExecutor;  
}
  • 对serviceMethod对象加入线程切换的操作,便于接收数据后通过Handler从子线程切换到主线程从而返回数据结果进行处理。(装饰模式)
    • 这里采用了装饰模式,ExecutorCallbackCall=装饰者,里面的OkHttpCall才是执行网络请求的。
    • 采用装饰模式的主要原因是做一些网络请求之外的一些操作,这个操作就是线程切换
    • OkHttpCall.enqueue()是进行异步请求的方法,当调用enqueue时,callback会回调到子线程中,然后通过handler切换到主线程。
  • 最终创建并返回一个OkHttpCall类型的网络请求对象
    • OkHttpCallOkHttp的包装类
    • 创建OkHttpCall类型的Call对象后还不能发送请求,还需要创建Request才可以发送网络请求

3.发送网络请求参数

  • 同步方式
    • 对网络请求接口的方法中的每个参数,利用对应ParameterHandler进行解析,再根据serviceMethod对象创建一个OkHttpRequest对象。
    • 通过OkHttpRequest发送网络请求
    • 对返回的数据使用通过GsonConverterFactory定义好的数据转换器解析返回的数据,得到一个Response<T>对象
    • serviceMethod中几乎保存了一个网络请求中所有需要的数据
      • 发起请求的Request对象是从serviceMethod.tpRequest()中获取的
      • 数据解析时的convert也是从serviceMethod.toResponse()中获取的
    • 为了提高效率,Request还会将已经执行过的网络请求进行缓存,存放在Map<Method, ServiceMethod> serviceMethodCache = new LinkedHashMap<>()
//源码:OkHttpCall#execute
@Override public Response<T> execute() throws IOException {
    okhttp3.Call call;

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

        if (creationFailure != null) {
            if (creationFailure instanceof IOException) {
                throw (IOException) creationFailure;
            } else {
                throw (RuntimeException) creationFailure;
            }
        }

        call = rawCall;
        if (call == null) {
            try {
                //获取OkHttp3的请求对象call
                call = rawCall = createRawCall();
            } catch (IOException | RuntimeException e) {
                creationFailure = e;
                throw e;
            }
        }
    }

    if (canceled) {
        call.cancel();
    }

    //通过OkHttp3发送网络请求并将返回的数据交给parseResponse解析
    return parseResponse(call.execute());
}

//源码:OkHttpCall#createRawCall
private okhttp3.Call createRawCall() throws IOException {
    //通过serviceMethod的toRequest()方法获取到Request对象
    Request request = serviceMethod.toRequest(args);
    //通过request对象创建一个OkHttp3的请求并返回
    okhttp3.Call call = serviceMethod.callFactory.newCall(request);
    if (call == null) {
        throw new NullPointerException("Call.Factory returned null.");
    }
    return call;
}

//源码:OkHttpCall#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 the response along.
    rawResponse = rawResponse.newBuilder()
        .body(new NoContentResponseBody(rawBody.contentType(), rawBody.contentLength()))
        .build();

    //获取返回数据的状态码进行检查
    int code = rawResponse.code();
    if (code < 200 || code >= 300) {
        try {
            // Buffer the entire body to avoid future I/O.
            ResponseBody bufferedBody = Utils.buffer(rawBody);
            return Response.error(bufferedBody, rawResponse);
        } finally {
            rawBody.close();
        }
    }

    if (code == 204 || code == 205) {
        return Response.success(null, rawResponse);
    }

    ExceptionCatchingRequestBody catchingBody = new ExceptionCatchingRequestBody(rawBody);
    try {
        //状态码检查完毕后将数据交给serviceMethod的toResponse()方法解析出需要的对象,在addConverterFactory中定义过
        T body = serviceMethod.toResponse(catchingBody);
        return Response.success(body, rawResponse);
    } catch (RuntimeException e) {
        // If the underlying source threw an exception, propagate that rather than indicating it was
        // a runtime exception.
        catchingBody.throwIfCaught();
        throw e;
    }
}

//源码:Servicemethod#toResponse
T toResponse(ResponseBody body) throws IOException {
    //responseConverter数组中的转换器是在创建Retrofit实例时添加
    return responseConverter.convert(body);
}
  • 异步方式
    • 对网络请求接口的方法中的每个参数,利用对应ParameterHandler进行解析,再根据serviceMethod对象创建一个OkHttpRequest对象。
    • 通过OkHttpRequest发送网络请求
    • 对返回的数据使用通过GsonConverterFactory定义好的数据转换器解析返回的数据,得到一个Response<T>对象
    • 进行线程切换从而在主线程处理数据
//源码:ExecutorCallAdapterFactory#enqueue
@Override public void enqueue(final Callback<T> callback) {
    if (callback == null) throw new NullPointerException("callback == null");
	
    //这里进行了异步请求,异步请求中又做了什么? —分析一
    delegate.enqueue(new Callback<T>() {
        @Override public void onResponse(Call<T> call, final Response<T> response) {
            //这里通过Handler进行了线程切换,便于在主线程显示结果
            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);
                }
            });
        }
    });
}

//分析1
//源码:
@Override public void enqueue(final Callback<T> callback) {
    if (callback == null) throw new NullPointerException("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 {
                //通过servieMethod获取到Request对象并包装成OkHttp3.Call
                call = rawCall = createRawCall();
            } catch (Throwable t) {
                failure = creationFailure = t;
            }
        }
    }

    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 {
              //数据解析,解析数据后返回的格式在Retrofit创建时通过addConverterFactory添加
              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();
            }
        }
    });
}

//分析2
//源码:Platform#Android
//线程切换是通过一开始创建Retrofit对象时Platform在检测到运行环境是Android时进行创建的:
static class Android extends Platform {
    //返回一个默认的回调执行器
    @Override public Executor defaultCallbackExecutor() {
		//获取到主线程的Handler,然后在主线程进行网络请求结果的展示
        return new MainThreadExecutor();
    }

    //创建一个默认的回调执行器工厂
    @Override CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {
        //如果没有使用RxJava则返回的是CallAdapter.Factory
        return new ExecutorCallAdapterFactory(callbackExecutor);
    }

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

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

4.解析数据

  • 异步方式:
    • 对返回的数据使用之前设置的数据转换器(GsonConverterFactory)解析返回的数据,返回Response对象
  • 同步方式:
    • 对返回的数据使用之前设置的数据转换器(GsonConverterFactory)解析返回的数据,返回Response对象

5.切换线程

  • 异步方式:
  • 同步方式:
    • 无线程切换

6.处理结果

  • 异步方式:
    • 在主线程处理返回的数据的结果
  • 同步方式:
    • 通过Response对象处理返回的数据的结果