Android-Retrofit

概述

  • Retrofit 通过注解将 Java Interface API 调用转化为 HTTP Call ,注解提供了 HTTP Call 的参数;
  • 使用者可以适配请求参数转化,响应数据转化,HTTP Call 对象转化,OkHttpClient 定制等;
  • 源码基于retrofit-2.7.1;

Converter

  • Converter
    public interface Converter<F, T> {
      @Nullable T convert(F value) throws IOException;
    }
    
    • 用于将 F 类型的对象转化为 T 类型的对象;
  • Converter.Factory
    abstract class Factory {
      //生成 Converter 对象,将 ResponseBody 类型转化为 Type 类型;
      public @Nullable Converter<ResponseBody, ?> responseBodyConverter(Type type,
          Annotation[] annotations, Retrofit retrofit) {
        return null;
      }
    
      //生成 Converter 对象,将 Type 类型转化为 RequestBody 类型;
      public @Nullable Converter<?, RequestBody> requestBodyConverter(Type type,
          Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
        return null;
      }
    
     //生成 Converter 对象,将 Type 类型转化为 String 类型
      public @Nullable Converter<?, String> stringConverter(Type type, Annotation[] annotations,
          Retrofit retrofit) {
        return null;
      }
    
      //返回参数化类型中的类型引元的上界类型
      protected static Type getParameterUpperBound(int index, ParameterizedType type) {
        return Utils.getParameterUpperBound(index, type);
      }
    
      //返回原生类型
      protected static Class<?> getRawType(Type type) {
        return Utils.getRawType(type);
      }
    }
    
    • responseBodyConverter 生成 Converter,将 ResponseBody 转化为 Type
    • requestBodyConverter 生成 Converter ,将 Type 转化为 RequestBody ;用于转化用 Body Part PartMap 注解的参数;
    • stringConverter 生成 Converter ,将 Type 转化为 String ;用于转化用 Field FieldMap Header HeaderMap Path Query QueryMap 注解的参数;

CallAdapter

  • CallAdapter
    //将 Call<R> 转化为 T 的适配器 
    public interface CallAdapter<R, T> {
      //返回 response type
      Type responseType();
      //将 Call<R> 转化为T
      T adapt(Call<R> call);
    }
    
  • CallAdapter.Factory
    abstract class Factory {
      //生成 CallAdapter
      public abstract @Nullable CallAdapter<?, ?> get(Type returnType, Annotation[] annotations,
          Retrofit retrofit);
    
      //返回参数化类型的类型引元的上界类型
      protected static Type getParameterUpperBound(int index, ParameterizedType type) {
        return Utils.getParameterUpperBound(index, type);
      }
    
      //返回原生类型
      protected static Class<?> getRawType(Type type) {
        return Utils.getRawType(type);
      }
    }
    
    • 返回匹配的 CallAdapter

ServiceMethod

  • ServiceMethod 可以理解为 Java Interface API 的静态映射;
  • 生成 ServiceMethod
    abstract class ServiceMethod<T> {
      static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
        //解析 Annotation ,生成RequestFactory
        RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);
    
        //返回类型不支持泛型或者通配符类型
        Type returnType = method.getGenericReturnType();
        if (Utils.hasUnresolvableType(returnType)) {
          throw methodError(method,
              "Method return type must not include a type variable or wildcard: %s", returnType);
        }
        //返回类型不支持 void 类型
        if (returnType == void.class) {
          throw methodError(method, "Service methods cannot return void.");
        }
        //生成 ServiceMethod
        return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
      }
    
      abstract @Nullable T invoke(Object[] args);
    }
    
    static RequestFactory parseAnnotations(Retrofit retrofit, Method method) {
      //通过 Method 生成 RequestFactory,RequestFactory#create 可以生成最终发起请求的 Request
      return new Builder(retrofit, method).build();
    }
    
    static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
        Retrofit retrofit, Method method, RequestFactory requestFactory) {
      boolean isKotlinSuspendFunction = requestFactory.isKotlinSuspendFunction;
      boolean continuationWantsResponse = false;
      boolean continuationBodyNullable = false;
    
      Annotation[] annotations = method.getAnnotations();
      Type adapterType;
      if (isKotlinSuspendFunction) {
        //kotlin 挂起函数 相关逻辑
      } else {
        // Method 返回类型(包括类型引元)
        adapterType = method.getGenericReturnType();
      }
    
      //根据 adapterType 找到匹配的 CallAdapter
      CallAdapter<ResponseT, ReturnT> callAdapter =
          createCallAdapter(retrofit, method, adapterType, annotations);
      //返回 CallAdapter 指定的 responseType
      Type responseType = callAdapter.responseType();
      //根据 responseType 找到匹配的Converter
      Converter<ResponseBody, ResponseT> responseConverter =
          createResponseConverter(retrofit, method, responseType);
    
      okhttp3.Call.Factory callFactory = retrofit.callFactory;
      if (!isKotlinSuspendFunction) {
        //生成ServiceMethod
        return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
      } else if (continuationWantsResponse) {
        //noinspection unchecked Kotlin compiler guarantees ReturnT to be Object.
        return (HttpServiceMethod<ResponseT, ReturnT>) new SuspendForResponse<>(requestFactory,
            callFactory, responseConverter, (CallAdapter<ResponseT, Call<ResponseT>>) callAdapter);
      } else {
        //noinspection unchecked Kotlin compiler guarantees ReturnT to be Object.
        return (HttpServiceMethod<ResponseT, ReturnT>) new SuspendForBody<>(requestFactory,
            callFactory, responseConverter, (CallAdapter<ResponseT, Call<ResponseT>>) callAdapter,
            continuationBodyNullable);
      }
    }
    
    • RequestFactory#parseAnnotations 通过 Method 生成 RequestFactoryRequestFactory#create 生成最终发起请求的 Request
    • RequestFactory.Builder 中关于各种注解的解析,可自行查看源码;
    • ServiceMethod#parseAnnotations
      • 先通过 Method 的返回类型(包括类型引元)找到匹配的 CallAdapter
      • 再通过 CallAdapter#responseAdapter 找到匹配的响应数据的 Converter
      • 通过 RequestFactory Call.Factory Converter CallAdapter 生成 CallAdaptedCallAdaptedServiceMethod 的子类;
  • ServiceMethod 的调用
    ReturnT invoke(Object[] args) {
      Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
      return adapt(call, args);
    }
    
    @Override protected ReturnT adapt(Call<ResponseT> call, Object[] args) {
        return callAdapter.adapt(call);
      }
    
    • Java Interface API 的调用就是 ServiceMethod 的调用,即调用 ServiceMethod#invoke
    • 根据 RequestFactory Call.Factory Converter 生成 OkHttpCall ,内部持有 OkhttpCall ,所以 Retrofit 的网络请求是由 OkHttp 处理的,并且无法更改;
    • 根据 CallAdapter 返回 Java Interface API 的返回类型的对象,并把 OkHttpCall 通过参数传递给 CallAdapter

Retrofit

  • Retrofit/Builder
    • Retrofit 对象是通过 Retrofit.Builder 生成的,有各种配置项;
    //缓存接口方法对应的 ServiceMethod
    private final Map<Method, ServiceMethod<?>> serviceMethodCache = new ConcurrentHashMap<>();
    //通过 Factory 生成的 Call 对象发起网络请求
    final okhttp3.Call.Factory callFactory;
    //用于拼接url
    final HttpUrl baseUrl;
    //请求数据/响应数据
    final List<Converter.Factory> converterFactories;
    // HTTP Call 对象转化器
    final List<CallAdapter.Factory> callAdapterFactories;
    //异步回调分发器
    final @Nullable Executor callbackExecutor;
    //ServiceMethod预加载
    final boolean validateEagerly;
    
    • serviceMethodCache 用于缓存 Java Interface API 对应的 ServiceMethod
    • callFactory 用于生成真正发情网络请求的 HTTP Call ;默认会创建一个 OkHttpClient
    • converterFactories 用于生成 请求数据/响应数据 转化器;要注意添加 Converter.Factory 的顺序;
    • callAdapterFactories 用于生成 HTTP Call 适配器,将 Retrofit 内置的 HTTP Call 转化为 Java Interface API 返回的 HTTP Call ;要注意添加 CallAdapter 的顺序;
    • callbackExecutor 表示异步回调分发器;默认是主线程;
    • validateEagerly 表示是否预加载 ServiceMethod ;如果为 true ,则在创建 Java Interfae 对应的动态代理对象时,预加载该 Java Interface所有 API 对应的 ServiceMethod
  • Retrofit#create
    public <T> T create(final Class<T> service) {
      // Java Interface 校验,ServiceMethod 预加载
      validateServiceInterface(service);
      //生成动态代理对象
      return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
          new InvocationHandler() {
            private final Platform platform = Platform.get();
            private final Object[] emptyArgs = new Object[0];
    
            @Override public @Nullable Object invoke(Object proxy, Method method,
                @Nullable Object[] args) throws Throwable {
              // 如果是 Object 的 API 调用,直接调用
              if (method.getDeclaringClass() == Object.class) {
                return method.invoke(this, args);
              }
              // 如果是 Java Interface 中的默认方法调用
              if (platform.isDefaultMethod(method)) {
                return platform.invokeDefaultMethod(method, service, proxy, args);
              }
              // 通过 ServiceMethod 代理调用
              return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
            }
          });
    }
    
    private void validateServiceInterface(Class<?> service) {
      // 指定的类必须为 Interface
      if (!service.isInterface()) {
        throw new IllegalArgumentException("API declarations must be interfaces.");
      }
    
      Deque<Class<?>> check = new ArrayDeque<>(1);
      check.add(service);
      while (!check.isEmpty()) {
        Class<?> candidate = check.removeFirst();
        if (candidate.getTypeParameters().length != 0) {
          //不支持参数化类型
          StringBuilder message = new StringBuilder("Type parameters are unsupported on ")
              .append(candidate.getName());
          if (candidate != service) {
            message.append(" which is an interface of ")
                .append(service.getName());
          }
          throw new IllegalArgumentException(message.toString());
        }
        Collections.addAll(check, candidate.getInterfaces());
      }
    
      // ServiceMethod 预加载
      if (validateEagerly) {
        Platform platform = Platform.get();
        for (Method method : service.getDeclaredMethods()) {
          if (!platform.isDefaultMethod(method) && !Modifier.isStatic(method.getModifiers())) {
            //加载 ServiceMethod
            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) {
          //通过 Method 及相关注解,生成 ServiceMethod 对象,并缓存
          result = ServiceMethod.parseAnnotations(this, method);
          serviceMethodCache.put(method, result);
        }
      }
      return result;
    }
    
    • 先校验指定的 Class ,必须为 Java Interface ,并且不是参数化类型;如果要预加载 ServiceMethod,则通过 Method 及相关的 Annotation 生成 ServiceMethod 并缓存;
    • 通过动态代理为指定的 Java Interface 生成动态代理对象,动态代理可以查看 Java-反射-动态代理
    • 动态代理对象的方法调用都会转发给绑定的 InvocationHandler#invoke 方法;具体调用流程后面会有详细介绍;
  • Retrofit#callAdapter
    //返回匹配 Java Interface API 返回类型的 CallAdapter
    public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) {
      return nextCallAdapter(null, returnType, annotations);
    }
    
    //返回匹配 Java Interface API 返回类型的 CallAdapter
    public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType,
        Annotation[] annotations) {
      Objects.requireNonNull(returnType, "returnType == null");
      Objects.requireNonNull(annotations, "annotations == null");
    
      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) {
          //CallAdapter.Factory 返回不为null,则匹配成功
          return adapter;
        }
      }
    }
    
    • callAdapterFactories 中遍历寻找能匹配 returnType 的CallAdapter;
  • Retrofit#requestBodyConverter
    // 返回 requestBody 的转化器
    public <T> Converter<T, RequestBody> requestBodyConverter(Type type,
        Annotation[] parameterAnnotations, Annotation[] methodAnnotations) {
      return nextRequestBodyConverter(null, type, parameterAnnotations, methodAnnotations);
    }
    
    // 返回 requestBody 的转化器
    public <T> Converter<T, RequestBody> nextRequestBodyConverter(
        @Nullable Converter.Factory skipPast, Type type, Annotation[] parameterAnnotations,
        Annotation[] methodAnnotations) {
      int start = converterFactories.indexOf(skipPast) + 1;
      for (int i = start, count = converterFactories.size(); i < count; i++) {
        Converter.Factory factory = converterFactories.get(i);
        Converter<?, RequestBody> converter =
            factory.requestBodyConverter(type, parameterAnnotations, methodAnnotations, this);
        if (converter != null) {
          //如果返回的 Converter 不为null,则匹配成功
          return (Converter<T, RequestBody>) converter;
        }
      }
    }
    
    • 返回转化 requestBody 的 Converter
    • 用于转化用 Body Part PartMap 注解的方法参数;
  • Retrofit#responseBodyConverter
    //返回
    public <T> Converter<ResponseBody, T> responseBodyConverter(Type type, Annotation[] annotations) {
      return nextResponseBodyConverter(null, type, annotations);
    }
    
    public <T> Converter<ResponseBody, T> nextResponseBodyConverter(
        @Nullable Converter.Factory skipPast, Type type, Annotation[] annotations) {
      int start = converterFactories.indexOf(skipPast) + 1;
      for (int i = start, count = converterFactories.size(); i < count; i++) {
        Converter<ResponseBody, ?> converter =
            converterFactories.get(i).responseBodyConverter(type, annotations, this);
        if (converter != null) {
          //如果返回 Converter 不为null,则匹配成功
          return (Converter<ResponseBody, T>) converter;
        }
      }
    }
    
    • 返回转化 responseBody 的 Converter
  • Retrofit#stringConverter
    //返回 `Conterver` ,用于将 `Type` 转化为 `String` ;
    public <T> Converter<T, String> stringConverter(Type type, Annotation[] annotations) {
      for (int i = 0, count = converterFactories.size(); i < count; i++) {
        Converter<?, String> converter =
            converterFactories.get(i).stringConverter(type, annotations, this);
        if (converter != null) {
          //noinspection unchecked
          return (Converter<T, String>) converter;
        }
      }
    
      //如果没有匹配到,则返回内置的 Converter
      return (Converter<T, String>) BuiltInConverters.ToStringConverter.INSTANCE;
    }
    
    • 返回 Converter ,用于将 Type 转化为 String
    • 用于转化用 Field FieldMap Header HeaderMap Path Query QueryMap 注解的方法参数;

总结

  • Retrofit 整体分为两部分:注解和代码;
    • 注解部分
      • Java Interfae API 中说明该网络请求的参数,包括请求方法(GET,POST等),请求参数,URL等;
    • 代码部分
      • Java Interface API 转换成对应的 ServiceMethod :根据设置的 Converter.Factory CallAdapter.Factory 找到匹配的 CallAdapter Converter,生成 RequestFactory
      • Java Interface API 调用时,根据 ServiceMethod 中的 RequestFactory Converter 以及传入的参数,生成 OkHttpCall ,并将 CallAdapter 转换后的结果返回;
  • Converter.Factory 中的 requestBodyConverter 比较独立;Converter.Factory 中的 responseBodyConverterCallAdapter.Factory 中的 responseType 是关联的,表示的是响应数据要转换的类型;
  • 配置 CallAdapterFactory ConverterFactory 时,需要注意前后顺序,具有特殊性的要排在前面,防止前面的通用性的 Factory 覆盖了 后面的 Factory ;
  • 关于解析注解的那部分,感兴趣的可以自行查看源码 RequestFactory#parseAnnotations,里面涉及 HTTP 协议的知识;

其他

  • 多个 baseUrl 配置
    • 如果涉及 OkHttpClient 配置不一样的,或者不同module之间,可以多个 Retrofit ;如果只是少数几个接口不一样,可以通过 Url 注解第一个参数动态设置 或者 注解方法时指定绝对路径静态设置;
    • 关于不同环境下的 baseUrl 切换,可以放在 OkHttpClientInterceptor 中动态切换;
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 一、什么是Retrofit A type-safe HTTP client for Android and Jav...
    andcoder阅读 797评论 2 3
  • 本文将顺着构建请求对象->构建请求接口->发起同步/异步请求的流程,分析Retrofit是如何实现的。 开始之前,...
    zhuhf阅读 1,649评论 0 10
  • Retrofit 源码解析 简单用法 Retrofit最简单的用法就是定义一个接口,创建Retrofit对象,调用...
    Kingty阅读 891评论 3 14
  • 安卓开发领域中,很多重要的问题都有很好的开源解决方案,例如Square公司提供网络请求 OkHttp , Retr...
    aaron688阅读 1,953评论 1 20
  • Retrofit这个开源库出来也有一定年头了,记得之前还是在V1.0的版本的时候,之前在三月份也写过一个Retro...
    lovejjfg阅读 1,473评论 0 5