参考资料:
retrofit注解大全:https://www.jianshu.com/p/e877b2f02966

https://blog.csdn.net/wan_dou_/article/details/116067728 (源码分析)

一、创建Retrofit实例

通过构造者设计模式构建retrofit实例

二、创建Service(接口)实例

public <T> T create(final Class<T> service) {
    //检测service定义的方法的合法性
    //将service中的方法反射缓存起来
    validateServiceInterface(service);

    //返回动态代理实例
    return (T)
        Proxy.newProxyInstance(
            service.getClassLoader(),
            new Class<?>[] {service},
            new InvocationHandler() {
              private final Object[] emptyArgs = new Object[0];

              @Override
              public @Nullable 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);
                }
                args = args != null ? args : emptyArgs;
                Platform platform = Platform.get();
                return platform.isDefaultMethod(method)
                    ? platform.invokeDefaultMethod(method, service, proxy, args)
                    : loadServiceMethod(method).invoke(args);
              }
            });
  }
  • validateServiceInterface

-> loadServiceMethod
存储Map<Method, ServiceMethod<?>>,将反射的结果保存起来,避免重复反射,影响性能。

ServiceMethod
-> parseAnnotations

|---- RequestFactory
-> Builder构造

 Builder(Retrofit retrofit, Method method) {
      this.retrofit = retrofit;
      this.method = method;
      //反射方法的注解
      this.methodAnnotations = method.getAnnotations();
      //反射方法的参数
      this.parameterTypes = method.getGenericParameterTypes();
      //反射方法参数的注解
      this.parameterAnnotationsArray = method.getParameterAnnotations();
    }

-> parseMethodAnnotation
解析HTTP请求方法上的各种注解:请求方法注解@GET等、请求头注解@Headers、标记注解@Multipart、@FormUrlEncoded

1)一个方法只能有一种HTTP注解
2)动态查询参数必需使用@Query注解
3)FormUrlEncoded与Multipart注解互斥,且只能用于带请求体的请求方法
4) 方法的返回类型不能是void

-> parseParameter
解析方法参数
->->parseParameterAnnotation
解析方法注解
各种方法参数的注解的报错日志就是这里打印的

->-> parseHttpMethodAndPath
  请求方法及请求url解析
->-> parseHeaders
  contentType解析

|---- HttpServiceMethod
-> parseAnnotations
createCallAdapter,创建CallAdapter对象
createResponseConverter,创建Converter对象
创建并返回HttpServiceMethod
- Proxy.newProxyInstance
返回动态代理创建的接口实例

  Platform platform = Platform.get();
            //获取Platform,判断方法是否是接口的默认方法。
            return platform.isDefaultMethod(method)
              ? platform.invokeDefaultMethod(method, service, proxy, args)
              : loadServiceMethod(method).invoke(args);

三、发起请求

所有的接口发起请求,最终都是通过动态代理走loadServiceMethod(method).invoke(args)的方法,也就是HttpServiceMethod的invoke方法。

那么,看懂这块的代码,你需要懂kotlin协程
参考一下博文https://www.jianshu.com/p/c9f123c21d82/

 CallAdapter<ResponseT, ReturnT> callAdapter =
        createCallAdapter();

 Converter<ResponseBody, ResponseT> responseConverter =
        createResponseConverter();

//不是挂起方法
 if (!isKotlinSuspendFunction) {
      return new CallAdapted<>();
    } else if (continuationWantsResponse) {
      //noinspection unchecked Kotlin compiler guarantees ReturnT to be Object.
      return (HttpServiceMethod<ResponseT, ReturnT>)
          new SuspendForResponse<>();
    } else {
      //noinspection unchecked Kotlin compiler guarantees ReturnT to be Object.
      return (HttpServiceMethod<ResponseT, ReturnT>)
          new SuspendForBody<>();
    }

//TODO 未完待续...

分类: Retrofit

0 条评论

发表回复

您的电子邮箱地址不会被公开。