Retrofit源码分析

Retrofit源码分析

1、优点

A:支持同步和异步请求操作

B:支持多种数据格式(Gson、Json、XML)

C:使用注解方式配置请求参数,简单易用

D:拓展性好,支持RxJava作为convertAdapter

源码分析

构建retrofit实例

Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("https://api.example.com/")
    .addConverterFactory(GsonConverterFactory.create())
    .build();

    MyApi api = retrofit.create(MyApi.class);
    Response user = api.getUser().execute();

构造方法

通过构造传参方式指定参数callFactory,baseUrl,converterFactories,callAdapterFactories,callbackExecutorvalidateEagerly值
  Retrofit(okhttp3.Call.Factory callFactory, HttpUrl baseUrl,
      List<Converter.Factory> converterFactories, List<CallAdapter.Factory> callAdapterFactories,
      @Nullable Executor callbackExecutor, boolean validateEagerly) {
    this.callFactory = callFactory;
    this.baseUrl = baseUrl;
    this.converterFactories = converterFactories; // Copy+unmodifiable at call site.
    this.callAdapterFactories = callAdapterFactories; // Copy+unmodifiable at call site.
    this.callbackExecutor = callbackExecutor;
    this.validateEagerly = validateEagerly;
  }

Builder分析

 public static final class Builder {
    // 平台类型
    private final Platform platform;
    // okhttp请求工厂类
    private @Nullable okhttp3.Call.Factory callFactory;
    // baseUrl
    private HttpUrl baseUrl;
    // 数据转换工厂集合
    private final List<Converter.Factory> converterFactories = new ArrayList<>();
    // call适配器工厂集合
    private final List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>();
    // 方法回调执行器
    private @Nullable Executor callbackExecutor;
    // 接口验证标志位
    private boolean validateEagerly;

    Builder(Platform platform) {
      this.platform = platform;
    }

    public Builder() {
      this(Platform.get());
    }
查看builder构造
 public Builder() {
      this(Platform.get());
    }

查看Platform

 private static final Platform PLATFORM = findPlatform();

  static Platform get() {
    return PLATFORM;
  }

  private static Platform findPlatform() {
    try {
      Class.forName("android.os.Build");
      if (Build.VERSION.SDK_INT != 0) {
        return new Android();
      }
    } catch (ClassNotFoundException ignored) {
    }
    try {
      Class.forName("java.util.Optional");
      return new Java8();
    } catch (ClassNotFoundException ignored) {
    }
    return new Platform();
  }
通过反射获取类名,从而得到平台类型是android还是java
 static class Android extends Platform {
    // 设定主线程回调执行器
    @Override public Executor defaultCallbackExecutor() {
      return new MainThreadExecutor();
    }

    @Override CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
    // 设定默认的callAdapterFactory
      if (callbackExecutor == null) throw new AssertionError();
      return new ExecutorCallAdapterFactory(callbackExecutor);
    }
    // 通过获取主线程looper的handler发送runnable执行数据
    static class MainThreadExecutor implements Executor {
      private final Handler handler = new Handler(Looper.getMainLooper());

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

baseUrl()

 /**
     * Set the API base URL.
     *
     * @see #baseUrl(HttpUrl)
     */
    public Builder baseUrl(String baseUrl) {
      checkNotNull(baseUrl, "baseUrl == null");
      // 通过okhttp类HttpUrl中parse将baseUrl转换为HttpUrl类型
      HttpUrl httpUrl = HttpUrl.parse(baseUrl);
      if (httpUrl == null) {
        throw new IllegalArgumentException("Illegal URL: " + baseUrl);
      }
      return baseUrl(httpUrl);
    }

    继续跟进 baseUrl(httpUrl)方法

      public Builder baseUrl(HttpUrl baseUrl) {
      checkNotNull(baseUrl, "baseUrl == null");
      List<String> pathSegments = baseUrl.pathSegments();
      if (!"".equals(pathSegments.get(pathSegments.size() - 1))) {
        throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl);
      }
      this.baseUrl = baseUrl;
      return this;
    }
通过baseUrl方法首先对baseUrl进行非空判断,并截取url判断是否以/结束,最后将baseUrl赋值给全局的baseUrl

addConverterFactory(GsonConverterFactory.create())

  /** Add converter factory for serialization and deserialization of objects. */
  // 通过该方法向convertFactories中添加数据转换工厂
    public Builder addConverterFactory(Converter.Factory factory) {
      converterFactories.add(checkNotNull(factory, "factory == null"));
      return this;
    }

继续查看Converter.Factory
Factory是一个抽象类,继续查看其子类,毫无悬念,GsonConverterFactory继承该类,如果我们
想使用其他方式对数据进行解析的话,只需要继承Converter.Factory方法,重写内部的解析方法即可

abstract class Factory {

public final class GsonConverterFactory extends Converter.Factory 
查看GsonConverterFactory.create()

  public static GsonConverterFactory create() {
    return create(new Gson());
  }

// create方法
  /**
   * Create an instance using {@code gson} for conversion. Encoding to JSON and
   * decoding from JSON (when no charset is specified by a header) will use UTF-8.
   */
  @SuppressWarnings("ConstantConditions") // Guarding public API nullability.
  public static GsonConverterFactory create(Gson gson) {
    if (gson == null) throw new NullPointerException("gson == null");
    return new GsonConverterFactory(gson);
  }

private GsonConverterFactory(Gson gson) {
    this.gson = gson;
  }

重写了请求和响应数据的解析方法

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

  @Override
  public Converter<?, RequestBody> requestBodyConverter(Type type,
      Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
    TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
    return new GsonRequestBodyConverter<>(gson, adapter);
  }

通过GsonRequestBodyConverter<>(gson, adapter),对数据进行转换

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

builder.build()方法

 /**
     * Create the {@link Retrofit} instance using the configured values.
     * <p>
     * Note: If neither {@link #client} nor {@link #callFactory} is called a default {@link
     * OkHttpClient} will be created and used.
     */
    public Retrofit build() {
      if (baseUrl == null) {
        throw new IllegalStateException("Base URL required.");
      }

      okhttp3.Call.Factory callFactory = this.callFactory;
      // 默认使用OKHttp进行网络请求
      if (callFactory == null) {
        callFactory = new OkHttpClient();
      }

      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> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
      callAdapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));

      // Make a defensive copy of the converters.
      // 配置数据转换工厂方法
      List<Converter.Factory> converterFactories =
          new ArrayList<>(1 + this.converterFactories.size());

      // Add the built-in converter factory first. This prevents overriding its behavior but also
      // ensures correct behavior when using converters that consume all types.
      converterFactories.add(new BuiltInConverters());
      converterFactories.addAll(this.converterFactories);

      return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
          unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
    }
build方法中对baseUrl、callFactory、callbackExecutor、callAdapterFactories、converterFactories进行赋值,然后通过retrofit构造方法将值进行传递,创建retrofit实例

retrofit.create(MyApi.class);

  @SuppressWarnings("unchecked") // Single-interface proxy creation guarded by parameter safety.
  public <T> T create(final Class<T> service) {
  // service接口判断
    Utils.validateServiceInterface(service);
    // 接口验证判断
    if (validateEagerly) {
      eagerlyValidateMethods(service);
    }
    // 使用动态代理方式
    return (T) Proxy.newProxyInstance(service.getClassLoader(),   // 动态生成接口的实现类 
    new Class<?>[] { service },         // 动态创建实例
        new InvocationHandler() {     // 将代理类的实现交给 InvocationHandler类作为具体的实现
          private final Platform platform = Platform.get();

          @Override public Object invoke(Object proxy, Method method, @Nullable 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<Object, Object> serviceMethod =
                (ServiceMethod<Object, Object>) loadServiceMethod(method);
                // 创建okHttpCall
            OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
            // 根据okHttpCal返回service接口类型数据
            return serviceMethod.adapt(okHttpCall);
          }
        });
  }

ServiceMethod

// 获取serviceMethod获取接口中的方法
    ServiceMethod<?, ?> loadServiceMethod(Method method) {
    // 先通过缓存获取method
    ServiceMethod<?, ?> result = serviceMethodCache.get(method);
    if (result != null) return result;

    // 同步缓存
    synchronized (serviceMethodCache) {
      result = serviceMethodCache.get(method);
      if (result == null) {
      // 构建serviceMethod实例
        result = new ServiceMethod.Builder<>(this, method).build();
        // private final Map<Method, ServiceMethod<?, ?>> serviceMethodCache = new ConcurrentHashMap<>();
        // 通过ConcurrentHashMap缓存method和result
        serviceMethodCache.put(method, result);
      }
    }
    return result;
  }

  下面跟进new ServiceMethod.Builder<>(this, method).build();


/** Adapts an invocation of an interface method into an HTTP call. */
// 适配一个接口方法用于http请求
final class ServiceMethod<R, T> {

    // Builder方法
   Builder(Retrofit retrofit, Method method) {
   // 设置retrofit实例
      this.retrofit = retrofit;
      // 设置method
      this.method = method;
      // 设置注解
      this.methodAnnotations = method.getAnnotations();
      // 设置泛型参数类型
      this.parameterTypes = method.getGenericParameterTypes();
      // 获取参数注解数组
      this.parameterAnnotationsArray = method.getParameterAnnotations();
    }

build方法

public ServiceMethod build() {
    // 创建callAdapter
      callAdapter = createCallAdapter();
      // 获取responseType
      responseType = callAdapter.responseType();
      // 获取responseConverter  响应转换器
      responseConverter = createResponseConverter();
    // 遍历注解方法并进行解析
      for (Annotation annotation : methodAnnotations) {
        parseMethodAnnotation(annotation);
      }
        // 省略判断代码
      int parameterCount = parameterAnnotationsArray.length;
      // 根据参数数量创建指定长队的ParameterHandler数组
      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);
        }
        // 解析注解参数置于parameterAnnotations数组中
        Annotation[] parameterAnnotations = parameterAnnotationsArray[p];
        //解析注解参数数据
        parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);
      }
      // 调用ServiceMethod构造方法创建serviceHandler实例
      return new ServiceMethod<>(this);
    }

解析参数ParameterHandler<?> parseParameter

private ParameterHandler<?> parseParameter(
        int p, Type parameterType, Annotation[] annotations) {
      ParameterHandler<?> result = null;
      for (Annotation annotation : annotations) {
        ParameterHandler<?> annotationAction = parseParameterAnnotation(
            p, parameterType, annotations, annotation);

        if (annotationAction == null) {
          continue;
        }

        if (result != null) {
          throw parameterError(p, "Multiple Retrofit annotations found, only one allowed.");
        }

        result = annotationAction;
      }

      if (result == null) {
        throw parameterError(p, "No Retrofit annotation found.");
      }

      return result;
    }

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

 private final ServiceMethod<T, ?> serviceMethod;
  private final @Nullable Object[] args;
// 通过构造设置serviceMethod和args
 OkHttpCall(ServiceMethod<T, ?> serviceMethod, @Nullable Object[] args) {
    this.serviceMethod = serviceMethod;
    this.args = args;
  }

return serviceMethod.adapt(okHttpCall);

 T adapt(Call<R> call) {
    return callAdapter.adapt(call);
  }
  默认返回call类型

  public interface CallAdapter<R, T> {
CallAdapter为接口类型如果我们想要自定义网络请求适配器,可以实现CallAdapter
类似final class RxJava2CallAdapter implements CallAdapter

enqueue异步请求方法

查看okHttpCall中enqueue方法

 @Override public void enqueue(final Callback<T> callback) {
  // 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赋值
          call = rawCall = createRawCall();
        } catch (Throwable t) {
          throwIfFatal(t);
          failure = creationFailure = t;
        }
      }
    }
    // 请求失败直接回调onFailed
    if (failure != null) {
      callback.onFailure(this, failure);
      return;
    }
    // 请求取消回调cancel
    if (canceled) {
      call.cancel();
    }
    // 异步执行请求
    call.enqueue(new okhttp3.Callback() {
      @Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
        Response<T> response;
        try {
        // 解析原始请求rawResponse
          response = parseResponse(rawResponse);
        } catch (Throwable e) {
        // 回调失败
          callFailure(e);
          return;
        }

        try {
        // 通过回调将解析后的数据进行传递
          callback.onResponse(OkHttpCall.this, response);
        } catch (Throwable t) {
          t.printStackTrace();
        }
      }
        // 数据解析失败,回调失败方法
      @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) {
          t.printStackTrace();
        }
      }
    });
  }

  里面有两个方法需要查看下
  parseResponse(rawResponse)
  callFailure(e);

  继续跟进查看如下

   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();
    // 回调error
    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();
      }
    }
    // 回调success
    if (code == 204 || code == 205) {
      rawBody.close();
      return Response.success(null, rawResponse);
    }

    ExceptionCatchingRequestBody catchingBody = new ExceptionCatchingRequestBody(rawBody);
    try {
      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;
    }
  }

 parseResponse通过rawResponse获取code码,根据code码返回response类型数据

 callFailure(e);

    private void callFailure(Throwable e) {
        try {
          callback.onFailure(OkHttpCall.this, e);
        } catch (Throwable t) {
          t.printStackTrace();
        }
      }
可见该方法直接简单回调了下onFailure(OkHttpCall.this, e)方法,将异常通过回调方法进行传递

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 if (creationFailure instanceof RuntimeException) {
          throw (RuntimeException) creationFailure;
        } else {
          throw (Error) creationFailure;
        }
      }
    // 单例方式创建call实例
      call = rawCall;
      if (call == null) {
        try {
        // 创建call实例
          call = rawCall = createRawCall();
        } catch (IOException | RuntimeException | Error e) {
          throwIfFatal(e); //  Do not assign a fatal error to creationFailure.
          creationFailure = e;
          throw e;
        }
      }
    }

    if (canceled) {
      call.cancel();
    }
    // 解析响应数据
    return parseResponse(call.execute());
  }

    // 通过serviceMethod
   private okhttp3.Call createRawCall() throws IOException {
   // 通过toCall方法获取call实例
    okhttp3.Call call = serviceMethod.toCall(args);
    if (call == null) {
      throw new NullPointerException("Call.Factory returned null.");
    }
    return call;
  }

  serviceMethod.toCall(args)方法源码查看

  // 通过方法参数构建HTTP请求
    /** Builds an HTTP request from method arguments. */
  okhttp3.Call toCall(@Nullable Object... args) throws IOException {
    // 构建RequestBuilder实例
    RequestBuilder requestBuilder = new RequestBuilder(httpMethod, baseUrl, relativeUrl, headers,
        contentType, hasBody, isFormEncoded, isMultipart);

    @SuppressWarnings("unchecked") // It is an error to invoke a method with the wrong arg types.
    ParameterHandler<Object>[] handlers = (ParameterHandler<Object>[]) parameterHandlers;

    int argumentCount = args != null ? args.length : 0;
    if (argumentCount != handlers.length) {
      throw new IllegalArgumentException("Argument count (" + argumentCount
          + ") doesn't match expected count (" + handlers.length + ")");
    }
    // 添加请求参数
    for (int p = 0; p < argumentCount; p++) {
      handlers[p].apply(requestBuilder, args[p]);
    }

    // 通过callFactory创建新的请求,实际上是调用okHttpClient进行请求
    return callFactory.newCall(requestBuilder.build());
  }

参考:https://blog.csdn.net/carson_ho/article/details/73732115

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值