Android中Retrofit2框架源码解析

Android中Retrofit2框架源码解析

一、Retrofit简介

1、阐述

Retrofit是一个基于Restful的HTTP网络请求框架(实际上内部真正网络请求是交由OkHttp去实现的),换句话说Retrofit实际上是一个负责网络请求接口的封装。

2、功能

  • 基于OkHttp遵循RestfulAPI设计风格

  • 通过注解配置网络请求参数

  • 支持同步(execute)和异步(enqueue)请求

  • 支持多种数据的解析(Gson,Json,XML,Protobuf)

  • 支持RxJava和Kotlin协程(近期加入)

  • 支持多平台,包括有Android、Java8、Guava、Scala等

3、优点

  • 功能强大,支持同步和异步,支持多种数据解析序列化格式、支持RxJava和Kotlin协程

  • 简洁易用,通过注解配置网络请求参数,采用了大量设计模式简化使用

  • 扩展性好,通过动态代理模式实现高度解耦。

4、注意

  • Retrofit是一个Restful的HTTP网络请求框架的封装,因其本质是委托OkHttp去实现网络请求的,而Retrofit仅仅负责网络请求接口的封装。

![](/Users/mikyou/Library/Application Support/marktext/images/2020-01-08-14-55-31-image.png)

  • APP应用通过Retrofit框架发起网络请求,实际上先利用Retrofit接口层(通过注解)封装请求参数,然后通过解析注解信息获取请求参数信息,组装这些请求参数(包括请求方式Header、 Url等),将这些组装后的参数按照OkHttp请求的规则,委托给OkHttp去完成真正的网络请求。

  • 最后在服务端返回响应数据后,OkHttp把原始数据交由Retrofit, Retrofit通过开始设置的解析器来解析返回的数据。

5、与其他网络库的对比

![](/Users/mikyou/Library/Application Support/marktext/images/2020-01-08-14-58-11-image.png)

二、Retrofit基本使用

1、添加必要的gradle依赖

由于Retrofit网络框架是把请求的实现委托给OkHttp框架实现的,所以需要加了OkHttp的库依赖

implementation 'com.squareup.retrofit2:retrofit:2.5.0'
implementation 'com.squareup.okhttp3:okhttp:3.13.1'

2、定义一个网络请求的接口,方法带请求注解

注意: API的声明定义必须是以接口形式注册的,此外这个接口有一些特殊要求,这个接口不能继承其他的接口。否则内部会抛出非法异常,Retrofit将 Http请求 抽象成 Java接口:采用 注解 描述网络请求参数 和配置网络请求参数

interface AccountApi {//请求API必须以接口形式定义且这个接口不能继承其他的接口
    @FormUrlEncoded
    @POST(value = "v1/api/login")
    fun createLogin(@Field(value = "username")username: String, @Field(value = "password") password: String): Call<UserWrapper>
}

3、请求注解说明

![](/Users/mikyou/Library/Application Support/marktext/images/2020-01-08-15-35-26-image.png)

注意: 网络请求的注解类型主要分为三种:

  • 1、网络请求方式的注解

    ![](/Users/mikyou/Library/Application Support/marktext/images/2020-01-08-15-36-35-image.png)

    @GET、@POST、@PUT、@DELETE、@HEAD、@PATH、@OPTIONS、@HTTP 分别对应着HTTP中的请求方式: GET、POST、PUT、DELETE、HEAD、PATH、OPTIONS(HTTP中还有TRACE、CONNECT请求方式未提供支持)

    此外,其中的@HTTP注解是一个特殊的注解,支持全链路URL请求,可以支持配置method、path(可以为全链路链接)、hasBody的三个注解参数,可以定制化满足需求。

    //一种特殊方式,使得在Retrofit中DELETE请求方式支持Body
    @HTTP(method = "DELETE", path = "test/test/test", hasBody = true)
    fun cancelLike(@Body map: Map<String, String>): Call<JsonElement>
  • 2、标记注解

    ![](/Users/mikyou/Library/Application Support/marktext/images/2020-01-08-15-52-31-image.png)

    @FormUrlEncoded: 表示发送form-encoded的数据,每个key-value需要使用@Field来注解key.

    @Multipart: 表示发送form-encoded的数(适用于文件上传的接口)

  • 3、请求参数注解

    ![](/Users/mikyou/Library/Application Support/marktext/images/2020-01-08-15-55-27-image.png)

4、创建Retrofit实例

fun getClient(baseUrl: String): Retrofit {
    return Retrofit.Builder()
                   .baseUrl(baseUrl)//配置baseUrl,一般为restful api的前缀URL
                   .addConverterFactory(GsonConveterFactory.create())//配置数据解析器
                   .addCallAdapterFactory(RxJavaCallAdapterFactory.create())//配置是否使用RxJavaCallAdapterFactory,如果不配置默认会使用DeafultCallAdapterFactory
                   .build()
}
  • 通过addCoverterFactory方法配置数据格式解析器.目前可支持: Gson、JackSon、XML、Protobuf、Moshi、Scalas等

  • 通过网络请求适配器,目前可支持: Guava(GuavaCallAdapterFactory)、RxJava(RxJavaCallAdapterFactory)、RxJava2、Scala、Java8、Kotlin以及默认的CallAdapter

5、创建网络接口实例

val accountApi: AccountApi = getClient(BASE_ACCOUNT_URL).create(AccountApi::class.java)

6、调用接口实例方法,对发送的请求进行封装,拿到Call实例

val okHttpCall: Call<UserWrapper> = accountApi.createLogin("mikyou", "123456")

7、执行发送网络请求(异步call.enqueue & 同步call.execute)

//发送异步请求
okHttpCall.enqueue(object: Callback<UserWrapper> {
    override fun onResponse(call: Call<UserWrapper>, asyncRes: Response<UserWrapper>) {
        println("异步请求的数据: ${asyncRes.body()?.toString()}")
    }
    override fun onFailure(call: Call<UserWrapper>, t: Throwable) {
        //handle error
    }
}

//发送同步请求
val syncRes = okHttpCall.execute()

三、Retrofit本质流程

一般从网络通信过程如下图:

网络请求的过程

  • 其实Retrofit的本质和上面是一样的套路
  • 只是Retrofit通过使用大量的设计模式进行功能模块的解耦,使得上面的过程进行得更加简单 & 流畅

实际上,Retrofit也是类似这样的流程:

四、Retrofit源码分析

大致流程:

![](/Users/mikyou/Library/Application Support/marktext/images/ba2e538b6f105981888aeb180bec65800f2b81ff.jpg)

1、Retrofit使用例子

//1、定义Github Service API
public interface Github {
    @GET("/repos/{owner}/{repo}/contributors")
    Call<List<Contributor>> contributors(@Path("owner") String owner, @Path("repo") String repo);
}

public static void main(String[] args) {
    //2、创建Retrofit实例
    Retrofit retrofit = new Retrofit.Builder()
             .baseUrl(BASE_URL)

             //配置CallAdapterFactory
             .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
             //配置CoverterAdapterFactory数据解析器
             .addConverterFactory(GsonConverterFactory.create())
             .build();
    //3、调用retrofit.create创建Github实例(内部借助动态代理生成代理类来创建代理类实例对象)
    Github github = retrofit.create(Github.class);
    //4、调用代理类请求API的方法,返回一个Call实例,实际上返回的一个是OkHttpCall实例
    Call<List<Contributor>> call = github.contributors("square", "retrofit");
    //5、最后调用Call的enqueue方法进行异步请求,如果是同步请求就调用Call的execute方法;实际上就是对应调用OkHttpCall的enqueue方法或execute方法
    call.enqueue(new Callback<List<Contributor>>() {
        @Override
        public void onResponse(Call<List<Contributor>> call, Response<List<Contributor>> response) {
                            List<Contributor> contributors = response.body();
                if (contributors != null) {
                    for (Contributor contributor : contributors) {
                        System.out.println(contributor.login + " (" + contributor.contributions + ")");
                    }
                }
        }

        @Override
        public void onFailure(Call<List<Contributor>> call, Throwable t){
          //handle on error
        }
    });

    //同步请求
    Response<List<Contributor>> response = call.execute();
}             

2、定义一个API对应的抽象Service接口

抽象接口类似Restful API风格,使用注解方式配置请求方式、请求URL、请求参数、Path等

    public interface GitHub {
        @GET("/repos/{owner}/{repo}/contributors")
        Call<List<Contributor>> contributors(@Path("owner") String owner, @Path("repo") String repo);
    }

3、然后,创建Retrofit实例,通过一个Retrofit内部的Builder来配置全局请求的参数

Retrofit retrofit = new Retrofit.Builder()
        .baseUrl(API_URL)//指定baseUrl
        .client(new OkhttpClient())//外部指定自定义的OkHttpClient,作用和callFactory方法一致,client方法内部就是委托给callFactory方法
        .callFactory(new OkHttpClient())//外部指定callFactory,若外部没有指定默认创建OkHttpClient实例
        .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
        .addConverterFactory(GsonConverterFactory.create())
        .build();

4、然后,进入Retrofit的Builder内部类中的build方法

    public Retrofit build() {
            //baseUrl不能为null
            if (baseUrl == null) {
                throw new IllegalStateException("Base URL required.");
            }
            //外部设置okhttp3.Call.Factory
            okhttp3.Call.Factory callFactory = this.callFactory;
            if (callFactory == null) {
                //默认创建一个OkHttpClient实例
                callFactory = new OkHttpClient();
            }

            //callbackExecutor数据回调执行器,用于线程的切换
            Executor callbackExecutor = this.callbackExecutor;
            if (callbackExecutor == null) {
            //如果外部没有单独指定,会根据当前Platform来指定默认的回调执行器
            //默认在Android平台指定的是MainThreadExecutor,实际上就是通过主线程Handler来实现线程的切换
                callbackExecutor = platform.defaultCallbackExecutor();
            }

            //初始化CallAdapter.Factory的集合
            List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);

    //默认加入一个Platform默认的DefaultCallAdapterFactory,并把回调执行器传入,用于调用时的线程切换            
    callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));
            //初始化CallAdapter.Factory的集合 
            List<Converter.Factory> converterFactories = new ArrayList<>(
                    1 + this.converterFactories.size() + platform.defaultConverterFactoriesSize());

            converterFactories.add(new BuiltInConverters());
            //加入外部指定数据解析器工厂类
            converterFactories.addAll(this.converterFactories);
            //加入Platform默认的数据解析工厂对象
        converterFactories.addAll(platform.defaultConverterFactories());
        //最后创建Retrofit实例,并传入callFactory(OkHttpClient)、baseUrl、converterFactories、callAdapterFactories、callbackExecutor、validateEagerly
            return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
                    unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
        }

5、创建好Retrofit实例,调用其create方法,通过动态代理+反射实例化出API接口实例Github

//外部调用
Github github = retrofit.create(Github.class);

//create方法源码实现
public <T> T create(final Class<T> service) {
        //1、验证外部API接口定义
        validateServiceInterface(service);
        //利用Proxy.newProxyInstance动态代理生成一个对应API接口类的代理类实例Github并返回
        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 {
                        //注意: 由动态代理原理可知,代理类实例Github的代理方法每次调用执行,都是通过触发InvocationHandler中的invoke方法来执行的,
                        //比如github.contributors("square", "retrofit");返回一个Call实例就是通过当前invoke方法中的loadServiceMethod(method).invoke(args != null ? args : emptyArgs);返回的。
                        if (method.getDeclaringClass() == Object.class) {
                            return method.invoke(this, args);
                        }
                        if (platform.isDefaultMethod(method)) {
                            return platform.invokeDefaultMethod(method, service, proxy, args);
                        }
                        return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
                    }
                });
}

    //Retrofit#validateServiceInterface,验证外部API接口定义
    private void validateServiceInterface(Class<?> service) {
    //API接口定义必须是一个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();
            //检查API接口类,不能带有泛型参数,如果泛型参数列表长度大于0就抛出异常
            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());
        }

        if (validateEagerly) {
            Platform platform = Platform.get();
            for (Method method : service.getDeclaredMethods()) {
                if (!platform.isDefaultMethod(method) && !Modifier.isStatic(method.getModifiers())) {
                    loadServiceMethod(method);
                }
            }
        }
    }

6、通过动态代理Proxy.newProxyInstance得到了代理接口类Github实例github,然后只要调用API接口的方法contributors就能拿到一个Call实例

GitHub github = retrofit.create(GitHub.class);//得到了代理接口类Github实例
//只要调用API接口的方法传入相应的请求参数,就能拿到一个Call实例
Call<List<Contributor>> call = github.contributors("square", "retrofit");

//由动态代理原理可知,代理类实例Github的代理方法contributors每次调用执行,都是通过触发InvocationHandler中的invoke方法来执行的,所以触发执行InvocationHandler中的invoke

//InvocationHandler#invoke方法
@Override
public @Nullable Object invoke(Object proxy, Method method, @Nullable Object[] args) throws Throwable {
        if (method.getDeclaringClass() == Object.class) {
                return method.invoke(this, args);
        }
        if (platform.isDefaultMethod(method)) {
                return platform.invokeDefaultMethod(method, service, proxy, args);
        }
        //github.contributors("square", "retrofit")获取Call是通过调用Retrofit中的loadServiceMethod(method)方法返回实例ServiceMethod的invoke()返回的
        return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
}

7、深入Retrofit中的loadServiceMethod,传入的参数是method,它是Github接口中定义的抽象接口方法contributors的Method对象实例。

//Github#contributors方法
@GET("/repos/{owner}/{repo}/contributors")
Call<List<Contributor>> contributors(@Path("owner") String owner, @Path("repo") String repo);

//Retrofit#loadServiceMethos方法,通过Method拿到对应的解析注解信息的ServiceMethod
    ServiceMethod<?> loadServiceMethod(Method method) {
        ServiceMethod<?> result = serviceMethodCache.get(method);
        //首先会去serviceMethodCache缓存ConcurrentHashMap中的查,如果缓存中存在就直接返回method对应的ServiceMethod
        if (result != null) return result;

        synchronized (serviceMethodCache) {
        //同步锁检查,可能会存在A线程正在解析并存入缓存中,此时B线程再次进入的时候,按道理可以直接在缓存中获取就可以了,所以还需要到serviceMethodCache中重新检查一次
            result = serviceMethodCache.get(method);
            //如果还是没有,所以需要执行ServiceMethod.parseAnnotations解析代理类接口方法中注解信息,比如请求方式、请求参数、Path等,然后解析注解信息后就会parseAnnotations转化成ServiceMethod
            if (result == null) {
                result = ServiceMethod.parseAnnotations(this, method);
                //然后再将解析后的ServiceMethod存入缓存serviceMethodCache中
                serviceMethodCache.put(method, result);
            }
        }
        return result;
    }

8、深入ServiceMethod中的parseAnnotations方法,传入接口代理方法Method对象以及Retrofit实例,返回一个ServiceMethod实例对象,实际上最后返回的是一个HttpServiceMethod对象实例。

  static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
    //通过RequestFactory的parseAnnotations解析返回一个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.");
    }

    //最后调用 HttpServiceMethod中的parseAnnotations,传入retrofit、method以及创建好的RequestFactory对象实际上最后返回的是一个HttpServiceMethod实例(ServiceMethod子类实例对象)
    return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
  }

9、深入RequestFactory类中的parseAnnotations方法,然后返回一个RequestFactory对象,并把从Method注解解析到的httpMethod、relativeUrl等信息

final class RequestFactory {
  static RequestFactory parseAnnotations(Retrofit retrofit, Method method) {
    return new Builder(retrofit, method).build();//通过RequestFactory的内部类Builder的build方法创建RequestFactory,传入retrofit实例和接口方法的Method对象
  }

  private final Method method;
  private final HttpUrl baseUrl;
  final String httpMethod;
  private final @Nullable String relativeUrl;
  private final @Nullable Headers headers;
  private final @Nullable MediaType contentType;
  private final boolean hasBody;
  private final boolean isFormEncoded;
  private final boolean isMultipart;
  private final ParameterHandler<?>[] parameterHandlers;
  final boolean isKotlinSuspendFunction;

  RequestFactory(Builder builder) {
    method = builder.method;
    baseUrl = builder.retrofit.baseUrl;
    httpMethod = builder.httpMethod;
    relativeUrl = builder.relativeUrl;
    headers = builder.headers;
    contentType = builder.contentType;
    hasBody = builder.hasBody;
    isFormEncoded = builder.isFormEncoded;
    isMultipart = builder.isMultipart;
    parameterHandlers = builder.parameterHandlers;
    isKotlinSuspendFunction = builder.isKotlinSuspendFunction;
  }
  ...  
}

    //RequestFactory#Builder#build  方法返回一个RequestFactory
    RequestFactory build() {
       //遍历方法中所有的methodAnnotations数组
      for (Annotation annotation : methodAnnotations) {
        //调用parseMethodAnnotation解析每一个注解
        parseMethodAnnotation(annotation);
      }

      if (httpMethod == null) {
        throw methodError(method, "HTTP method annotation is required (e.g., @GET, @POST, etc.).");
      }

      if (!hasBody) {
        if (isMultipart) {
          throw methodError(method,
              "Multipart can only be specified on HTTP methods with request body (e.g., @POST).");
        }
        if (isFormEncoded) {
          throw methodError(method, "FormUrlEncoded can only be specified on HTTP methods with "
              + "request body (e.g., @POST).");
        }
      }

      int parameterCount = parameterAnnotationsArray.length;
      parameterHandlers = new ParameterHandler<?>[parameterCount];
      for (int p = 0, lastParameter = parameterCount - 1; p < parameterCount; p++) {
        parameterHandlers[p] =
            parseParameter(p, parameterTypes[p], parameterAnnotationsArray[p], p == lastParameter);
      }

      if (relativeUrl == null && !gotUrl) {
        throw methodError(method, "Missing either @%s URL or @Url parameter.", httpMethod);
      }
      if (!isFormEncoded && !isMultipart && !hasBody && gotBody) {
        throw methodError(method, "Non-body HTTP method cannot contain @Body.");
      }
      if (isFormEncoded && !gotField) {
        throw methodError(method, "Form-encoded method must contain at least one @Field.");
      }
      if (isMultipart && !gotPart) {
        throw methodError(method, "Multipart method must contain at least one @Part.");
      }

      return new RequestFactory(this);//创建一个RequestFactory的对象并返回
    }

    //RequestFactory#parseMethodAnnotation解析方法Method对象中的注解
    private void parseMethodAnnotation(Annotation annotation) {
      if (annotation instanceof DELETE) {//解析HTTP中的DELETE注解和Path
        parseHttpMethodAndPath("DELETE", ((DELETE) annotation).value(), false);
      } else if (annotation instanceof GET) {//解析HTTP中的GET注解和Path
        parseHttpMethodAndPath("GET", ((GET) annotation).value(), false);
      } else if (annotation instanceof HEAD) {//解析HTTP中的HEAD注解和Path
        parseHttpMethodAndPath("HEAD", ((HEAD) annotation).value(), false);
      } else if (annotation instanceof PATCH) {//解析HTTP中的PATCH注解和Path
        parseHttpMethodAndPath("PATCH", ((PATCH) annotation).value(), true);
      } else if (annotation instanceof POST) {//解析HTTP中的POST注解和Path
        parseHttpMethodAndPath("POST", ((POST) annotation).value(), true);
      } else if (annotation instanceof PUT) {//解析HTTP中的PUT注解和Path
        parseHttpMethodAndPath("PUT", ((PUT) annotation).value(), true);
      } else if (annotation instanceof OPTIONS) {//解析HTTP中的OPTIONS注解和Path
        parseHttpMethodAndPath("OPTIONS", ((OPTIONS) annotation).value(), false);
      } else if (annotation instanceof HTTP) {//解析HTTP中的HTTP注解和Path
        HTTP http = (HTTP) annotation;
        parseHttpMethodAndPath(http.method(), http.path(), http.hasBody());
      } else if (annotation instanceof retrofit2.http.Headers) {
        String[] headersToParse = ((retrofit2.http.Headers) annotation).value();
        if (headersToParse.length == 0) {
          throw methodError(method, "@Headers annotation is empty.");
        }
        headers = parseHeaders(headersToParse);//解析HTTP中设置的Headers
      } else if (annotation instanceof Multipart) {
        if (isFormEncoded) {
          throw methodError(method, "Only one encoding annotation is allowed.");
        }
        isMultipart = true;
      } else if (annotation instanceof FormUrlEncoded) {
        if (isMultipart) {
          throw methodError(method, "Only one encoding annotation is allowed.");
        }
        isFormEncoded = true;
      }
    }

    //RequestFactory#parseHttpMethodAndPath解析方法Method和Path
    private void  (String httpMethod, String value, boolean hasBody) {
      if (this.httpMethod != null) {
        throw methodError(method, "Only one HTTP method is allowed. Found: %s and %s.",
            this.httpMethod, httpMethod);
      }
      this.httpMethod = httpMethod;//初始化请求方式httpMethod
      this.hasBody = hasBody;//初始化是否含有Body

      if (value.isEmpty()) {
        return;
      }

      //如果相对URL存在query,比如repos/{owner}/{repo}/contributors?query=xxx
      int question = value.indexOf('?');
      if (question != -1 && question < value.length() - 1) {
        // 确保相对URL中不存在命名参数如果存在就抛出异常
        String queryParams = value.substring(question + 1);
        Matcher queryParamMatcher = PARAM_URL_REGEX.matcher(queryParams);
        if (queryParamMatcher.find()) {
          throw methodError(method, "URL query string \"%s\" must not have replace block. "
              + "For dynamic query parameters use @Query.", queryParams);
        }
      }

      this.relativeUrl = value;//通过注解解析可以拿到部分相对URL来初始化relativeUrl
      this.relativeUrlParamNames = parsePathParameters(value);
    }

   //parsePathParameters解析path中的请求参数名
   static Set<String> parsePathParameters(String path) {
      Matcher m = PARAM_URL_REGEX.matcher(path);
      Set<String> patterns = new LinkedHashSet<>();
      while (m.find()) {
        patterns.add(m.group(1));
      }
      return patterns;
    }

10、拿到RequestFactory对象后,回到parseAnnotations中的HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory),深入HttpServiceMethod中的parseAnnotations方法,最后实际上返回一个CallAdapted对象(HttpServiceMethod的子类)

    static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
            Retrofit retrofit, Method method, RequestFactory requestFactory) {
        boolean isKotlinSuspendFunction = requestFactory.isKotlinSuspendFunction;//是否是Kotlin中的suspend函数
        boolean continuationWantsResponse = false;
        boolean continuationBodyNullable = false;

        Annotation[] annotations = method.getAnnotations();
        Type adapterType;
        if (isKotlinSuspendFunction) {
          //... kotlin suspend function暂不做分析
        } else {
        //拿到Method对象返回值类型作为adapterType,adapterType用于筛选对应CallAdapterFactory并返回CallAdapter,
            adapterType = method.getGenericReturnType();
        }

        //关键点一:通过adapterType调用createCallAdapter方法获得对应method的CallAdapter,如果返回值类型是Observable那么CallAdapter就是来自RxJavaCallAdapterFactory的ResponseCallAdapter;如果是Call那么CallAdapter就是默认的DefaultCallAdapterFactory的CallAdapter   
        CallAdapter<ResponseT, ReturnT> callAdapter = createCallAdapter(retrofit, method, adapterType, annotations);

        //通过callAdapter拿到responseType 
        Type responseType = callAdapter.responseType();
        ...
        //关键点二: 然后利用responseType调用createResponseConverter方法拿到对应的Coverter数据解析器对象
        Converter<ResponseBody, ResponseT> responseConverter = createResponseConverter(retrofit, method, responseType);

        okhttp3.Call.Factory callFactory = retrofit.callFactory;//拿到callFacrtory这里一般就是OkHttpClient对象
        if (!isKotlinSuspendFunction) {//如果不是kotlin中的suspend函数
            //会返回一个CallAdapted对象,CallAdapted是一个HttpServiceMethod的子类,传入requestFactory,callFactory、reponseConverter、callAdapter
            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);
        }
    }

    //CallAdapted是一个HttpServiceMethod的子类,内部有adapt核心方法
    static final class CallAdapted<ResponseT, ReturnT> extends HttpServiceMethod<ResponseT, ReturnT> {
        private final CallAdapter<ResponseT, ReturnT> callAdapter;

        CallAdapted(RequestFactory requestFactory, okhttp3.Call.Factory callFactory,
                    Converter<ResponseBody, ResponseT> responseConverter,
                    CallAdapter<ResponseT, ReturnT> callAdapter) {
            super(requestFactory, callFactory, responseConverter);
            this.callAdapter = callAdapter;
        }

        @Override
        protected ReturnT adapt(Call<ResponseT> call, Object[] args) {
            //关键点三: 外部调用CallAdapted的方法,实际上最后调用各自CallAdapter的adapt方法,传入的call就是OkHttpCall对象
            return callAdapter.adapt(call);
        }
    }
关键点一: 通过createCallAdapter方法传入adapterType来筛选找到对应的CallAdapterFactory并返回对应CallAdapter
//关键点一:通过adapterType调用createCallAdapter方法获得对应method的CallAdapter,如果返回值类型是Observable那么CallAdapter就是来自RxJavaCallAdapterFactory的ResponseCallAdapter;如果是Call那么CallAdapter就是默认的DefaultCallAdapterFactory的CallAdapter
    CallAdapter<ResponseT, ReturnT> callAdapter = createCallAdapter(retrofit, method, adapterType, annotations);

    //createCallAdapter
    private static <ResponseT, ReturnT> CallAdapter<ResponseT, ReturnT> createCallAdapter(
            Retrofit retrofit, Method method, Type returnType, Annotation[] annotations) {
        try {
            //内部调用Retrofit中的callAdapter方法,传入returnType和annotations来确定使用哪个CallAdapterFactory
            return (CallAdapter<ResponseT, ReturnT>) retrofit.callAdapter(returnType, annotations);
        } catch (RuntimeException e) { // Wide exception range because factories are user code.
            throw methodError(method, e, "Unable to create call adapter for %s", returnType);
        }
    }

然后,深入Retrofit中的callAdapter方法

    public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) {
        return nextCallAdapter(null, returnType, annotations);//内部再调用nextCallAdapter获取对应的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;
        //遍历callAdapterFactories集合,通过Retrofit创建addCallAdapterFactory最终都会添加到这个集合中
        for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
            //然后调用callAdapterFactories集合中所有的CallAdapterFactory的get方法,如果符合条件的就会返回adapter实例,如果不符合直接返回null,进行下一个CallAdapterFactory的get调用,直到找到第一个符合条件的CallAdapterFactory,并返回它对应的CallAdapter
            CallAdapter<?, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this);
            if (adapter != null) {
                return adapter;
            }
        }
       //没找到抛出异常
       ...
    } 
关键点二: 利用responseType调用createResponseConverter方法拿到对应的Coverter数据解析器对象
//关键点二: 然后利用responseType调用createResponseConverter方法拿到对应的Coverter数据解析器对象
 Converter<ResponseBody, ResponseT> responseConverter = createResponseConverter(retrofit, method, responseType);

    //createResponseConverter
    private static <ResponseT> Converter<ResponseBody, ResponseT> createResponseConverter(
            Retrofit retrofit, Method method, Type responseType) {
        Annotation[] annotations = method.getAnnotations();
        try {
            //内部调用Retrofit中的responseBodyConverter方法,传入responseType和annotations来确定使用哪个Converter数据解析器对象
            return retrofit.responseBodyConverter(responseType, annotations);
        } catch (RuntimeException e) { // Wide exception range because factories are user code.
            throw methodError(method, e, "Unable to create converter for %s", responseType);
        }
    }

然后,深入Retrofit中的responseBodyConverter方法

    public <T> Converter<ResponseBody, T> responseBodyConverter(Type type, Annotation[] annotations) {
        return nextResponseBodyConverter(null, type, annotations);//内部再调用nextResponseBodyConverter获取对应的CallAdapter
    }

    public <T> Converter<ResponseBody, T> nextResponseBodyConverter(
            @Nullable Converter.Factory skipPast, Type type, Annotation[] annotations) {
        Objects.requireNonNull(type, "type == null");
        Objects.requireNonNull(annotations, "annotations == null");

        int start = converterFactories.indexOf(skipPast) + 1;
        //遍历converterFactories集合,通过Retrofit创建addCoverterFactory最终都会添加到这个集合中
        for (int i = start, count = converterFactories.size(); i < count; i++) {
            //然后调用converterFactories集合中所有的CoverterFactory的responseBodyConverter方法,如果符合条件的就会返回Converter实例,如果不符合直接返回null,进行下一个CoverterFactory的responseBodyConverter调用,直到找到第一个符合条件的Converter,并返回它对应的Converter
            Converter<ResponseBody, ?> converter = converterFactories.get(i).responseBodyConverter(type, annotations, this);
            if (converter != null) {
                //noinspection unchecked
                return (Converter<ResponseBody, T>) converter;
            }
        }

       //没找到抛出异常
       ...
    }

   转载规则


《Android中Retrofit2框架源码解析》 mikyou 采用 知识共享署名 4.0 国际许可协议 进行许可。
 上一篇
剑指Offer 剑指Offer
剑指Offer1、二维数组中的查找(1) 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。 解
下一篇 
bytedance算法题集 bytedance算法题集
bytedance1、最长公共前缀 编写一个函数来查找字符串数组中的最长公共前缀。 如果不存在公共前缀,返回空字符串 “”。 示例 1: 输入: [“flower”,”flow”,”flight”]输出: “fl”示例 2: 输入: [“d
  目录