Retrofit

Retrofit

Retrofit是一款基于OkHttp再封装的网络框架,主要是支持多种数据转换Convert,例如Gson,xml,多种请求适配CallAdapte,例如RxJava,LiveData等。

下面来对Retrofit做个拆解,拆分出每个类的具体作用,并且再做个串联。

先介绍Retrofit


Call

[图片上传失败...(image-d380b0-1574651953315)]

这里的Call是对于请求的封装,可以看到接口里面有同步执行execute(),异步执行enqueue()等方法,真正的实现类是OkHttpCall,OkHttpCall是在Retrofit对于请求的真正实现,而ExecutorCallbackCall只是Retrofit内DefaultCallAdapterFactory实现的CallAdapter对应的Call,内部真正执行请求的相关方法还是OkHttpCall,ExecutorCallbackCall只是添加了回调执行器callbackExecutor。

DefaultCallAdapterFactory是Retrofit提供的默认的请求适配工厂,Retrofit会根据接口方法的返回值类型解析到相应的CallAdapterFactory,然后生成对应的请求适配器CallAdapter,请求适配器CallAdapter只是对请求Call做了适配,比如可以将原始请求Call的基础上添加线程切换逻辑,可以支持适配RxJava,LiveData等,而请求适配器内部真正执行网络请求的其实还是OkHttpCall。

那么接下来详细分析下OkHttpCall吧,而ExecutorCallBack就很简单

private final RequestFactory requestFactory;//根据接口方法上的注解生成请求的请求工厂
private final Object[] args;//接口请求方法的参数
private final okhttp3.Call.Factory callFactory;//请求的工厂,即OkHttpClient
private final Converter responseConverter;//响应数据转换器

private volatile boolean canceled;//请求是否取消

@GuardedBy("this")
private @Nullable okhttp3.Call rawCall;//原始请求
@GuardedBy("this") // Either a RuntimeException, non-fatal Error, or IOException.
private @Nullable Throwable creationFailure;
@GuardedBy("this")
private boolean executed;//是否执行

异步请求

  @Override public void enqueue(final Callback callback) {
    ...

    synchronized (this) {
        //一个请求只能执行一次,再次执行就抛异常
      if (executed) throw new IllegalStateException("Already executed.");
      executed = true;

      call = rawCall;
      failure = creationFailure;
      if (call == null && failure == null) {
        try {
          call = rawCall = createRawCall();//创建OkHttp.Call请求
        } catch (Throwable t) {
          throwIfFatal(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) {
        Response response;
        try {
          response = parseResponse(rawResponse);//解析响应数据
        } catch (Throwable e) {
          throwIfFatal(e);
          callFailure(e);
          return;
        }

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

      @Override public void onFailure(okhttp3.Call call, IOException e) {
        callFailure(e);
      }

      private void callFailure(Throwable e) {
        try {
          callback.onFailure(OkHttpCall.this, e);//失败回调
        } catch (Throwable t) {
          throwIfFatal(t);
          t.printStackTrace(); // TODO this is not great
        }
      }
    });
  }

  1. 创建出OkHttp.Call
  2. 执行OkHttp.Call的enqueue()执行异步请求,解析响应的数据OkHttp.Response,解析成Retrofit.Response
  3. 执行请求回调

再看下创建请求

  private okhttp3.Call createRawCall() throws IOException {
    okhttp3.Call call = callFactory.newCall(requestFactory.create(args));
    if (call == null) {
      throw new NullPointerException("Call.Factory returned null.");
    }
    return call;
  }
  1. requestFactory.create(args),args是接口请求方法的参数,内部会解析各种注解,最终生成Okhttp.Request,这里会用到ParameterHandler来解析各个参数。
  2. 调用callFactory.newCall(),生成OkHttp.Call,CallFactory就是OkHttpClient

再看下解析Okhttp.Response 解析程Retrofit.Response的方法

  Response 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.
    //先将ResponseBody移除,因为ResponseBody里面的source是唯一的又状态的对象
    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) {
    //响应码为204,205的情况
      rawBody.close();
      return Response.success(null, rawResponse);
    }
    
    //对响应体做个包装
    ExceptionCatchingResponseBody catchingBody = new ExceptionCatchingResponseBody(rawBody);
    try {
        //利用响应转换器器responseConverter对数据流转换成实体类
      T body = responseConverter.convert(catchingBody);
      //生成Retrofit.Response
      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;
    }
  }

  1. 先将rawBody移除Okhttp.Response,因为rawBody是有状态的对象,防止多次读取,所以先移除
  2. 对rawBody做封装,便于更好的读数据和处理异常
  3. 利用ResponseConvert生成响应实体类,构造出Retrofit.Response返回

关于OkHttpCall的同步请求方式同理,不在分析

继续再看下ExecutorCallbackCall

  static final class ExecutorCallbackCall implements Call {
    final Executor callbackExecutor;
    final Call delegate;

    ExecutorCallbackCall(Executor callbackExecutor, Call delegate) {
      this.callbackExecutor = callbackExecutor;
      this.delegate = delegate;
    }

    @Override public void enqueue(final Callback callback) {
      checkNotNull(callback, "callback == null");

      delegate.enqueue(new Callback() {
        @Override public void onResponse(Call call, final Response 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 call, final Throwable t) {
          callbackExecutor.execute(new Runnable() {
            @Override public void run() {
              callback.onFailure(ExecutorCallbackCall.this, t);
            }
          });
        }
      });
    }

    @Override public boolean isExecuted() {
      return delegate.isExecuted();
    }

    @Override public Response execute() throws IOException {
      return delegate.execute();
    }

    @Override public void cancel() {
      delegate.cancel();
    }

    @Override public boolean isCanceled() {
      return delegate.isCanceled();
    }

    @SuppressWarnings("CloneDoesntCallSuperClone") // Performing deep clone.
    @Override public Call clone() {
      return new ExecutorCallbackCall<>(callbackExecutor, delegate.clone());
    }

    @Override public Request request() {
      return delegate.request();
    }
  }

  1. delegate其实是OkhttpCall类,只是会在异步调用的时候添加了回调执行器callbackExecutor的线程切换逻辑

CallAdapter

CallAdapter是由CallAdapter.Factory中生成的,而CallAdapter.Factory是Retrofit中特别重要的一个功能,主要的目的是为了创造CallAdapter,用来适配RxJava等。将默认的网络请求执行器(OkHttpCall)转换成适合被不同平台来调用的网络请求执行器形式

先看下CallAdapter

public interface CallAdapter {

  //返回的是HTTP响应体的数据类型,最终会传给ResponseConvert去做数据转换
  Type responseType();

  //返回需要把Retrofit.Call做适配的类型。就是请求接口的返回值,有Retrofit.Call,Observable等
  T adapt(Call call);
  
  //CallAdapter的工厂
  abstract class Factory {
    
    //根据请求方法的参数,返回适合的适配器CallAdapter,无法处理就返回null
    public abstract @Nullable CallAdapter get(Type returnType, Annotation[] annotations,
        Retrofit retrofit);
   
    //提取泛型类的index对应的原始类型,比如Map,如果index为1,那么返回Runnable类型
    protected static Type getParameterUpperBound(int index, ParameterizedType type) {
      return Utils.getParameterUpperBound(index, type);
    }
   
    //提取泛型类的原始类型,比如List返回List.class
    protected static Class getRawType(Type type) {
      return Utils.getRawType(type);
    }
  }
}

这里只分析CallAdapter.Factory的子类RxJava2CallAdapterFactory,其他的同理

  
  //返回RxJava2CallAdapterFactory的默认实例,默认是同步请求。这里一般使用默认同步的,所以网络请求的线程会调用RxJava的线程池
  public static RxJava2CallAdapterFactory create() {
    return new RxJava2CallAdapterFactory(null, false);
  }

  //返回RxJava2CallAdapterFactory的实例,请求是异步的
  public static RxJava2CallAdapterFactory createAsync() {
    return new RxJava2CallAdapterFactory(null, true);
  }

 
  //创建一个同步的RxJava2CallAdapterFactory,传入Scheduler用来调度线程
  public static RxJava2CallAdapterFactory createWithScheduler(Scheduler scheduler) {
    if (scheduler == null) throw new NullPointerException("scheduler == null");
    return new RxJava2CallAdapterFactory(scheduler, false);
  }

  private final @Nullable Scheduler scheduler;//请求线程的调度器,可以为null
  private final boolean isAsync;//标志网络请求同步还是异步
  //私有的构造函数
  private RxJava2CallAdapterFactory(@Nullable Scheduler scheduler, boolean isAsync) {
    this.scheduler = scheduler;
    this.isAsync = isAsync;
  }



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

    if (rawType == Completable.class) {
      // Completable is not parameterized (which is what the rest of this method deals with) so it
      // can only be created with a single configuration.
      //如果rawType是Completable.class 那么就构造RxJava2CallAdapter返回
      return new RxJava2CallAdapter(Void.class, scheduler, isAsync, false, true, false, false,
          false, true);
    }

    boolean isFlowable = rawType == Flowable.class;//是否是Flowable.class
    boolean isSingle = rawType == Single.class;//是否是Single.class
    boolean isMaybe = rawType == Maybe.class;//是否是Maybe.class
    //如果上面都为false,并且也不是Observable.class,那么就表示无法构造出RxJava2CallAdapter,就返回null,交由其他请求适配器工厂构造出合适的请求适配器
    if (rawType != Observable.class && !isFlowable && !isSingle && !isMaybe) {
      return null;
    }

    boolean isResult = false;
    boolean isBody = false;
    Type responseType;
    if (!(returnType instanceof ParameterizedType)) {
      String name = isFlowable ? "Flowable"
          : isSingle ? "Single"
          : isMaybe ? "Maybe" : "Observable";
      throw new IllegalStateException(name + " return type must be parameterized"
          + " as " + name + " or " + name + "");
    }

    Type observableType = getParameterUpperBound(0, (ParameterizedType) returnType);
    Class rawObservableType = getRawType(observableType);
    if (rawObservableType == Response.class) {
      if (!(observableType instanceof ParameterizedType)) {
        throw new IllegalStateException("Response must be parameterized"
            + " as Response or Response");
      }
      responseType = getParameterUpperBound(0, (ParameterizedType) observableType);
    } else if (rawObservableType == Result.class) {
      if (!(observableType instanceof ParameterizedType)) {
        throw new IllegalStateException("Result must be parameterized"
            + " as Result or Result");
      }
      responseType = getParameterUpperBound(0, (ParameterizedType) observableType);
      isResult = true;
    } else {
      responseType = observableType;
      isBody = true;
    }
    //构造出RxJava2CallAdapter
    return new RxJava2CallAdapter(responseType, scheduler, isAsync, isResult, isBody, isFlowable,
        isSingle, isMaybe, false);
  }
  1. 根据上面的方法可以看出来,如果请求的返回值的rawType是Completable.class,Flowable.class,Single.class,Maybe.class或者Observable.class,那么RxJava2CallAdapterFactory回生成RxJava2CallAdapter

Converter.Factory

数据转换器工厂类

//把请求数据的ResponseBody转换成对应数据结构的转换器
public @Nullable Converter responseBodyConverter(Type type,
    Annotation[] annotations, Retrofit retrofit) {
  return null;
}

//把请求数据转换成RequestBody对象的数据转换器
public @Nullable Converter requestBodyConverter(Type type,
    Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
  return null;
}

 //把相应类型转换成String类型的数据转换器
public @Nullable Converter stringConverter(Type type, Annotation[] annotations,
    Retrofit retrofit) {
  return null;
}

//泛型类的index的原始类型,比如泛型类型为Map,index为1,那么返回类型为Runnable
protected static Type getParameterUpperBound(int index, ParameterizedType type) {
  return Utils.getParameterUpperBound(index, type);
}

//转换泛型类型为原始类型,比如List,那么返回List.class
protected static Class getRawType(Type type) {
  return Utils.getRawType(type);
}

数据转换器工厂的实现类有BuiltInConverters,GsonConverterFactory,OptionalConverterFactory(适用于Java 8 和Android 24 以上)三种,逻辑是一样的,这里只分析GsonConverterFactory

  
  //创建默认的工厂实例,传入Gson对象用于解析和编码JSON
  public static GsonConverterFactory create() {
    return create(new Gson());
  }

  
  //根据传进来的gson对象,创建默认的转换器工厂
  public static GsonConverterFactory create(Gson gson) {
    if (gson == null) throw new NullPointerException("gson == null");
    return new GsonConverterFactory(gson);
  }

  private final Gson gson;

  private GsonConverterFactory(Gson gson) {
    this.gson = gson;
  }
   
  //HTTP请求体的数据转换器
  @Override
  public Converter responseBodyConverter(Type type, Annotation[] annotations,
      Retrofit retrofit) {
    TypeAdapter adapter = gson.getAdapter(TypeToken.get(type));
    return new GsonResponseBodyConverter<>(gson, adapter);
  }

  //把请求对象转换成HTTP Request对象的数据转换器
  @Override
  public Converter requestBodyConverter(Type type,
      Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
    TypeAdapter adapter = gson.getAdapter(TypeToken.get(type));
    return new GsonRequestBodyConverter<>(gson, adapter);
  }
 

下面再分别看一下GsonResponseBodyConverter,GsonRequestBodyConverter两个类

final class GsonRequestBodyConverter implements Converter {
  private static final MediaType MEDIA_TYPE = MediaType.get("application/json; charset=UTF-8");//多媒体类型
  private static final Charset UTF_8 = Charset.forName("UTF-8");//字符集

  private final Gson gson;
  private final TypeAdapter adapter;

  GsonRequestBodyConverter(Gson gson, TypeAdapter adapter) {
    this.gson = gson;
    this.adapter = adapter;
  }

    //把传进来的请求对象转换成对应的OkHttp.RequestBody,用于发起网络请求
  @Override public RequestBody convert(T value) throws IOException {
    Buffer buffer = new Buffer();
    Writer writer = new OutputStreamWriter(buffer.outputStream(), UTF_8);
    JsonWriter jsonWriter = gson.newJsonWriter(writer);
    adapter.write(jsonWriter, value);
    jsonWriter.close();
    return RequestBody.create(MEDIA_TYPE, buffer.readByteString());
  }
}
final class GsonResponseBodyConverter implements Converter {
  private final Gson gson;
  private final TypeAdapter adapter;

  GsonResponseBodyConverter(Gson gson, TypeAdapter adapter) {
    this.gson = gson;
    this.adapter = adapter;
  }

  //把OkHttp.ResponseBody的数据流用Gson解析程相应类型的对象,TypeAdapter和Jsonreader都是Gson解析Json的用法
  @Override public T convert(ResponseBody value) throws IOException {
    JsonReader jsonReader = gson.newJsonReader(value.charStream());
    try {
      T result = adapter.read(jsonReader);
      if (jsonReader.peek() != JsonToken.END_DOCUMENT) {
        throw new JsonIOException("JSON document was not fully consumed.");
      }
      return result;
    } finally {
      value.close();
    }
  }
}

你可能感兴趣的:(Retrofit)