美文网首页
Android-Retrofit

Android-Retrofit

作者: 写代码的阿毛 | 来源:发表于2020-03-03 15:09 被阅读0次

    概述

    • 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 中动态切换;

    相关文章

      网友评论

          本文标题:Android-Retrofit

          本文链接:https://www.haomeiwen.com/subject/elhbkhtx.html