Android Retrofit的应用及源码解析

retrofit github地址
retrofit官方文档地址
Retrofit是square公司开源的一款类型安全的http请求框架,用于Java和Android程序。Retrofit实际上在Okhttp的基础之上又进行了一次封装,将Okhttp的使用方式转换成了对象的方法调用的形式
我写的关于okHttp文章

下面是Retrofit的简单调用

public interface RetrofitInterface {
    @GET
    Call getRetrofitGet(Map params);

    @POST
    Call getRetrofitPost(Map params);

    @PUT
    Call getRetrofitPut(Map params);

    @DELETE
    Call getRetrofitDelete(Map params);
}

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(url)
                .build();

        RetrofitInterface retrofitInterface=retrofit.create(RetrofitInterface.class);
        Call call = null;
        if(requestType==GET_TYPE){
            call=retrofitInterface.getRetrofitGet(params);
        }else if(requestType==POST_TYPE){
            call=retrofitInterface.getRetrofitPost(params);
        }else if(requestType== DELETE_TYPE){
            call=retrofitInterface.getRetrofitDelete(params);
        }else if(requestType==PUT_TYPE){
            call=retrofitInterface.getRetrofitPut(params);
        }
        call.enqueue(new Callback() {
            @Override
            public void onResponse(Call call, Response response) {
                String result=response.body().toString();
                callBack.onSuccess(response.code(),result);
            }

            @Override
            public void onFailure(Call call, Throwable t) {
                callBack.onError((Exception) t);
            }
        });

以上就是一个使用Retrofit发起http请求的完整的例子,首先,定义一个服务接口类,声明要发起请求的方法;然后在需要发起网络请求的地方生成一个retrofit实例,利用retrofit.create()生成一个服务接口类的对象,然后调用对象的方法完成请求

使用Retrofit的七步骤

  • 添加Retrofit依赖,网络权限
  • 定义接收服务器返回数据的Bean
  • 创建网络请求的接口,使用注解(动态代理,核心)
  • builder模式创建Retrofit实例,converter,calladapter...
  • 创建接口实例,调用具体的网络请求
  • call同步/异步网络请求
  • 处理服务器返回的数据

Retrofit网络通信八步骤

  • 创建Retrofit实例
  • 定义网络请求接口,并为接口中的方法添加注解
  • 通过动态代理生成网络请求对象
  • 通过网络请求适配器将网络请求对象进行平台适配
  • 通过网络请求执行器,发送网络请求(call)
  • 通过数据解析器解析数据
  • 通过会掉执行器,切换线程
  • 用户在主线程处理返回结果

Retrofit的优点

  • 超级解耦 ,接口定义、接口参数、接口回调不在耦合在一起
  • 可以配置不同的httpClient来实现网络请求,如okhttp、httpclient
  • 支持同步、异步、Rxjava
  • 可以配置不同反序列化工具类来解析不同的数据,如json、xml
  • 请求速度快,使用方便灵活简洁

Retrofit注解

在上面的例子中,有看到我使用的注释,在Retrofit中有如下注解

注解名 说明
网络请求方法
@GET get请求
@POST post请求
@PUT put请求
@DELETE delete请求
@PATCH patch请求,该请求是对put请求的补充,用于更新局部资源
@HEAD head请求
@OPTIONS options请求
@HTTP 用于替换以上7个注解的作用及更多拓展功能
网络请求参数
@Headers 用于添加固定请求头,可以同时添加多个,通过该注解的请求头不会相互覆盖,而是共同存在
@Header 作为方法的参数传入,用于添加不固定的header,它会更新已有请求头
@Body 多用于Post请求发送非表达数据,根据转换方式将实例对象转化为对应字符串传递参数,比如使用Post发送Json数据,添加GsonConverterFactory则是将body转化为json字符串进行传递
@Filed 多用于Post方式传递参数,需要结合@FromUrlEncoded使用,即以表单的形式传递参数
@FiledMap 多用于Post请求中的表单字段,需要结合@FromUrlEncoded使用
@Part 用于表单字段,Part和PartMap与@multipart注解结合使用,适合文件上传的情况
@PartMap 用于表单字段,默认接受类型是Map,可用于实现多文件上传
@Path 用于Url中的占位符
@Query 用于Get请求中的参数
@QueryMap 与Query类似,用于不确定表单参数
@Url 指定请求路径
标记
@FromUrlCoded 表示请求发送编码表单数据,每个键值对需要使用@Filed注解
@Multipart 表示请求发送form_encoded数据(使用于有文件上传的场景),每个键值对需要用@Part来注解键名,随后的对象需要提供值
@Streaming 表示响应用字节流的形式返回,如果没有使用注解,默认会把数据全部载入到内存中,该注解在下载大文件时特别有用

Retrofit使用

网络请求方法

1.@GET、@POST、@PUT、@DELETE、@HEAD分别对应 HTTP中的网络请求方式
2.@HTTP替换@GET、@POST、@PUT、@DELETE、@HEAD注解的作用 及 更多功能拓展
具体使用:通过属性method、path、hasBody进行设置

    //get请求
    @GET("url")//@GET为 调用此方法会发起get请求 “user”我get请求的url地址
    Call geResponse();//T为请求完成返回的ResponseBody
      //拼接完地址为http://192.168.0.1/url

    @POST("url/post") //post请求
      Call getPostResponse();

      @HTTP(method = "GET", path = "user/keys", hasBody = false)
      Call getHttpResponse();

请求标记

1.@FormUrlEncoded
表示发送form-encoded的数据,每个键值对需要用@Filed来注解键名,随后的对象需要提供值。

/**
         *表明是一个表单格式的请求(Content-Type:application/x-www-form-urlencoded)
         * Field("username") 表示将后面的 String name 中name的取值作为 username 的值
         */
        @POST("/form")
        @FormUrlEncoded
        Call testFormUrlEncoded1(@Field("username") String name, @Field("age") int age);

2.@Multipart

        /**
         * {@link Part} 后面支持三种类型,{@link RequestBody}、{@link okhttp3.MultipartBody.Part} 、任意类型
         * 除 {@link okhttp3.MultipartBody.Part} 以外,其它类型都必须带上表单字段({@link okhttp3.MultipartBody.Part} 中已经包含了表单字段的信息),
         */
        @POST("/form")
        @Multipart
        Call testFileUpload1(@Part("name") RequestBody name, @Part("age") RequestBody age, @Part MultipartBody.Part file);

网络请求参数

1.@Header & @Headers
添加请求头 &添加不固定的请求头
区别在于使用场景和使用方式

  • 使用场景:@Header用于添加不固定的请求头,@Headers用于添加固定的请求头
  • 使用方式:@Header作用于方法的参数;@Headers作用于方法
// @Header
@GET("user")
Call getResponse(@Header("Authorization") String authorization)

// @Headers
@Headers("Authorization: authorization")
@GET("user")
Call getResponse()

2.@Body
以 Post方式 传递 自定义数据类型 给服务器,如果提交的是一个Map,那么作用相当于 @Field,不过Map要经过 FormBody.Builder 类处理成为符合 Okhttp 格式的表单。也可以做上传json格式数据,直接传入实体它会自动转为json,这个转化方式可以是GsonConverterFactory定义的,@Body可以传递自定义类型数据给服务器,多用于post请求发送非表单数据,比如用传递Json格式数据,它可以注解很多东西,比如HashMap、实体类等。

       @FormUrlEncoded
       @POST("url/emails")
       Call getPsotDataBodyResponse(@Body RequestBody body);

3.@Field & @FieldMap
发送 Post请求 时提交请求的表单字段,与 @FormUrlEncoded 注解配合使用

  • @Field 请求参数注解,提交请求的表单字段,必须要添加,而且需要配合@FormUrlEncoded使用,与get的Query一样
  • @FieldMap 请求参数注解,与@Field作用一致,用于不确定表单个数是传参数
      @FormUrlEncoded//请求格式注解,请求实体是一个From表单,每个键值对需要使用@File注解
     @POST("url/post") //post请求
      Call getPostResponse2(@Field ("id") int id, @Field ("username") String username);


      @FormUrlEncoded
     @POST("url/post") 
      Call getPostResponse3(@FieldMap Map map);

4.@Part & @PartMap
发送 Post请求 时提交请求的表单字段,与@Field的区别:功能相同,但携带的参数类型更加丰富,包括数据流,所以适用于 有文件上传 的场景,与 @Multipart 注解配合使用

          /**
         * {@link Part} 后面支持三种类型,{@link RequestBody}、{@link okhttp3.MultipartBody.Part} 、任意类型
         * 除 {@link okhttp3.MultipartBody.Part} 以外,其它类型都必须带上表单字段({@link okhttp3.MultipartBody.Part}
         * 中已经包含了表单字段的信息),
         */
        @POST("/form")
        @Multipart
        Call testFileUpload1(@Part("name") RequestBody name
                                              , @Part("age") RequestBody age, @Part MultipartBody.Part file);

        /**
         * PartMap 注解支持一个Map作为参数,支持 {@link RequestBody } 类型,
         * 如果有其它的类型,会被{@link retrofit2.Converter}转换,如后面会介绍的 使用{@link com.google.gson.Gson} 的 {@link retrofit2.converter.gson.GsonRequestBodyConverter}
         * 所以{@link MultipartBody.Part} 就不适用了,所以文件只能用 @Part MultipartBody.Part 
         */
        @POST("/form")
        @Multipart
        Call testFileUpload2(@PartMap Map args, @Part MultipartBody.Part file);

        @POST("/form")
        @Multipart
        Call testFileUpload3(@PartMap Map args);

5.@Query和@QueryMap
用于 @GET 方法的查询参数(Query = Url 中 ‘?’ 后面的 key-value)
如:url = http://www.println.net/?cate=android,其中,Query = cate
配置时只需要在接口方法中增加一个参数即可:
用法与Post的@Field & @FieldMap相似

    @GET("url")
     Call geResponse2(@Query("id") int id, @Query("username") String username);
    //其实就是(int id,String username)在两个参数的前面加上参数注释@query
     //拼接完地址为http://192.168.0.1/url?id=10&username=lucifer

    @GET("url")
     Call geResponse3(@QueryMap Map map);
    //与上面一样,只不过传入的id,与username都被放到了Map集合里面
     //拼接完地址为http://192.168.0.1/url?id=10&username=lucifer

6.@Path
URL地址的缺省值

@GET("url/{userId}")//@GET为 调用此方法会发起get请求 “user”我get请求的url地址
    Call geResponse(@Path("userId") String userId);//T为请求完成返回的ResponseBody
      //拼接完地址为http://192.168.0.1/url/{userId} path指url中的可变参数

7.@Url
直接传入一个请求的 URL变量 用于URL设置

        @GET
        Call testUrlAndQuery(@Url String url, @Query("showAll") boolean showAll);
       // 当有URL注解时,@GET传入的URL就可以省略
       // 当GET、POST...HTTP等方法中没有设置Url时,则必须使用 {@link Url}提供

Retrofit源码解析

我们先看看创建Retrofit构造方法

public final class Retrofit {
//网络请求缓存,如:请求方法、请求头、请求体,各种适配器等
  private final Map> serviceMethodCache = new ConcurrentHashMap<>();
 //okhttp工厂,真正发送交易的处理类
  final okhttp3.Call.Factory callFactory;
//请求url前半部,基地址
  final HttpUrl baseUrl;
//数据转换器工厂集
  final List converterFactories;
//网络请求适配器工厂集
  final List callAdapterFactories;
//异步请求结果线程切换执行器
  final @Nullable Executor callbackExecutor;
//标志位、是否马上解析接口方法
  final boolean validateEagerly;

  Retrofit(okhttp3.Call.Factory callFactory, HttpUrl baseUrl,
      List converterFactories, List 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;
  }

...

          public static final class Builder {
//适配平台,通常默认android
    private final Platform platform;
//okhttp网络请求工厂,默认okhttp
    private @Nullable okhttp3.Call.Factory callFactory;
//请求地址
    private @Nullable HttpUrl baseUrl;
//数据转换器集,用于生产数据转换器,默认GsonConverterFactory
    private final List converterFactories = new ArrayList<>();
//网络请求适配器,如RxJava2CallAdapterFactory
    private final List callAdapterFactories = new ArrayList<>();
//执行异步回调的线程切换
    private @Nullable Executor callbackExecutor;
//是否立即解析接口注解方法
    private boolean validateEagerly;

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

    public Builder() {
      this(Platform.get());
    }

    Builder(Retrofit retrofit) {
      platform = Platform.get();
      callFactory = retrofit.callFactory;
      baseUrl = retrofit.baseUrl;

      // Do not add the default BuiltIntConverters and platform-aware converters added by build().
      for (int i = 1,
          size = retrofit.converterFactories.size() - platform.defaultConverterFactoriesSize();
          i < size; i++) {
        converterFactories.add(retrofit.converterFactories.get(i));
      }

      // Do not add the default, platform-aware call adapters added by build().
      for (int i = 0,
          size = retrofit.callAdapterFactories.size() - platform.defaultCallAdapterFactoriesSize();
          i < size; i++) {
        callAdapterFactories.add(retrofit.callAdapterFactories.get(i));
      }

      callbackExecutor = retrofit.callbackExecutor;
      validateEagerly = retrofit.validateEagerly;
    }

...

    public Retrofit build() {
      if (baseUrl == null) {//baseurl不能是空
        throw new IllegalStateException("Base URL required.");
      }
//callFactory是类okhttp3.Call.Factory的对象,如果自己没有设置了OkHttp对象,则会自己创建一个。
      okhttp3.Call.Factory callFactory = this.callFactory; //返回Http的call
      if (callFactory == null) {//实现请求的工厂类 
        callFactory = new OkHttpClient();
      }
//回调方法执行器
      Executor callbackExecutor = this.callbackExecutor;
 //没有指定的话,就用构造器中赋值的platform中的,也就是将回调放在主线程
      if (callbackExecutor == null) {
        callbackExecutor = platform.defaultCallbackExecutor();
      }
// 将配置的网络适配器进行保护性拷贝
      // Make a defensive copy of the adapters and add the default Call adapter.
      List callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
//添加默认的网络适配器,也就是ExecutorCallAdapterFactory
      callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));
// 与网络适配器的排序不同,默认的BuiltInConverters放在第一位,后面才是添加的
      // Make a defensive copy of the converters.
      List converterFactories = new ArrayList<>(
          1 + this.converterFactories.size() + platform.defaultConverterFactoriesSize());

      // 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);
      converterFactories.addAll(platform.defaultConverterFactories());

      return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
          unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
    }

我们可以看到,Retrofit与OkHttp的源码类似,都是使用了建造者模式
最开始创建Retrofit.Build对象,创建Builder实例时调用的是Builder的无参构造放法,里面调用了Builder(Platform)这个构造方法,传入的是Platform.get()返回数据,这个方法是获取适配平台,默认是Android

class Platform {
private static final Platform PLATFORM = findPlatform();//PLATFORM 默认的方法

  static Platform get() {//Build中调用此方法
    return PLATFORM;
  }
}
  private static Platform findPlatform() {
    try {
//如果是安卓系统,就返回Android()
      Class.forName("android.os.Build");
      if (Build.VERSION.SDK_INT != 0) {
        return new Android(); //返回android 
      }
    } catch (ClassNotFoundException ignored) {
    }
    try {
// Java8()
      Class.forName("java.util.Optional");
      return new Java8();
    } catch (ClassNotFoundException ignored) {
    }
    return new Platform();
  }

  static class Android extends Platform { //创建android 的平台
//请求结果毁掉是用的Executor,如果Builder没有赋值给callbackExecutor,就会调用这个方法赋值
    @IgnoreJRERequirement // Guarded by API check.
    @Override boolean isDefaultMethod(Method method) {
      if (Build.VERSION.SDK_INT < 24) {
        return false;
      }
      return method.isDefault();
    }

    @Override public Executor defaultCallbackExecutor() {
      return new MainThreadExecutor();
    }
  //Builder里的callAdapter.Factory,最后会在build里赋值给adapterFactories,作为默认的网络请求适配器
    @Override List defaultCallAdapterFactories(
        @Nullable Executor callbackExecutor) {
      if (callbackExecutor == null) throw new AssertionError();

      DefaultCallAdapterFactory executorFactory = new DefaultCallAdapterFactory(callbackExecutor);
      return Build.VERSION.SDK_INT >= 24
        ? asList(CompletableFutureCallAdapterFactory.INSTANCE, executorFactory)
        : singletonList(executorFactory);
    }

    @Override int defaultCallAdapterFactoriesSize() {
      return Build.VERSION.SDK_INT >= 24 ? 2 : 1;
    }

    @Override List defaultConverterFactories() {
      return Build.VERSION.SDK_INT >= 24
          ? singletonList(OptionalConverterFactory.INSTANCE)
          : Collections.emptyList();
    }

    @Override int defaultConverterFactoriesSize() {
      return Build.VERSION.SDK_INT >= 24 ? 1 : 0;
    }

    static class MainThreadExecutor implements Executor {

      //默认线程切换是切换到主线程
      private final Handler handler = new Handler(Looper.getMainLooper());

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

baseUrl

就是将String类型的url,经过合格性检测,拆分存储,再转换成HttpUrl赋值给baseUrl。

    /**
     * Set the API base URL.
     *
     * @see #baseUrl(HttpUrl)
     */
    public Builder baseUrl(String baseUrl) {
      checkNotNull(baseUrl, "baseUrl == null");
      return baseUrl(HttpUrl.get(baseUrl));
    }

    public Builder baseUrl(HttpUrl baseUrl) {
      checkNotNull(baseUrl, "baseUrl == null");
      List pathSegments = baseUrl.pathSegments();
      if (!"".equals(pathSegments.get(pathSegments.size() - 1))) {
        throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl);
      }
      this.baseUrl = baseUrl;
      return this;
    }

在这里可以看到,baseUrl路径必须以"/"结尾

addConverterFactory

//将转换工厂保存到converterFactories中,在构造器中,已经add了一个BuiltInConverters
public Builder addConverterFactory(Converter.Factory factory) {
  converterFactories.add(checkNotNull(factory, "factory == null"));
  return this;
}

我们可以在这里添加一个GsonConverterFactory,下面来看看它是如何转换的。

public final class GsonConverterFactory extends Converter.Factory {

  @Override
  public Converter responseBodyConverter(Type type, Annotation[] annotations,
      Retrofit retrofit) {
    TypeAdapter adapter = gson.getAdapter(TypeToken.get(type));
    //返回对应的Converter对象
    return new GsonResponseBodyConverter<>(gson, adapter);
  }
}

final class GsonRequestBodyConverter implements Converter {

    @Override public T convert(ResponseBody value) throws IOException {
    JsonReader jsonReader = gson.newJsonReader(value.charStream());
    try {
      //将ResponseBody转为泛型对象
      return adapter.read(jsonReader);
    } finally {
      value.close();
    }
  }

通过convert转换的类型,是在调用responseBodyConverter创建对象时传入的请求接口的返回类的泛型。也就是例子中的HttpResult。

如果要自定义Converter来实现请求结果转化,按上面那样就可以了,使用工厂方法模式。

  • 继承Converter,在convert方法中返回转换后的结果,比如GsonRequestBodyConverter中是把ResponseBody转成自己需要转的类型。
  • 继承Converter.Factory,在responseBodyConverter中将相应的Converter对象返回。
  • 在Retrofit的创造器中调用addConverterFactory添加相应的Converter.Factory。

总结

可以看到在创建Builder实例的设配平台时,将工作线程切换到了主线程,这也是后面可以通过主线程回调返回请求数据的原因。

retrofit与OkHttp一样最后会执行build()方法。在build方法中baseUrl不能等于null,如果是null就会抛出IllegalStateException异常,然后会在build方法中创建okhttp3.Call.Factory callFactory对象,在文章开始开始的时候说过,retrofit是基于okHttp的请求的,也就是在这个方法中创建了OkHttp3的对象。然后又创建了一个回调函数Executor callbackExecutor, 他是在Platform中Android的MainThreadExecutor();他是一个Handle,默认的主线程回调执行器。然后通过一系列操作,最后创建Retrofit对象。

defaultCallbackExecutor是返回回调执行的Executor,返回的MainThreadExecutor是使用handler让回调操作在主线程执行。如果在Builder中没有指定回调的Executor,会调用defaultCallbackExecutor指定异步网络请求的回调在主线程执行。

defaultCallAdapterFactory则是指定默认网络适配器工厂为ExecutorCallAdapterFactory,调用接口方法返回的Call,就是这个类创建的。具体等后面使用其功能再介绍。

retrofit.create

我们通过Retrofit的create方法来创建实例,这个方法是Retrofit的核心,内部采用动态代理,将咱们自定义的网络请求接口转换成一个RetrofitInterface 对象,RetrofitInterface 就是咱们Retrofit中的具体请求对象,里面封装了网络请求所必须的全部信息,包括请求方法、url、请求头、请求体等网络配置参数!

  public  T create(final Class service) {
    Utils.validateServiceInterface(service);
 //是否提前通过注解加验证加载请求接口,会将接口中的方法都解析成ServiceMethod,并加入serviceMethodCache缓存中
    if (validateEagerly) {
      //注释一
      eagerlyValidateMethods(service);
    }
    //返回了动态代理对象用来实现代理接口
    return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class[] { service },
        new InvocationHandler() {//将代理类的实现交给 InvocationHandler类作为具体的实现
          private final Platform platform = Platform.get();
          private final Object[] emptyArgs = new Object[0];
            //被代理执行的方法,是通过在InvocationHandler中的invoke方法调用的
          @Override public @Nullable Object invoke(Object proxy, Method method,
              @Nullable Object[] args) throws Throwable {
            // Object的方法直接调用原方法
            // If the method is a method from Object then defer to normal invocation.
            if (method.getDeclaringClass() == Object.class) {
              return method.invoke(this, args);
            }
        //android默认为false,不走
            if (platform.isDefaultMethod(method)) {
              return platform.invokeDefaultMethod(method, service, proxy, args);
            }
            return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
          }
        });
  }

我们先看注释一处的代码

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

我们可以看到在可以看到在eagerlyValidateMethods这个方法中,遍历获取咱们自定义类的全部方法,。isDefaultMethod默认为false可以忽略并且方法不是静态的,就一定会走到loadServiceMethod(method)方法

  ServiceMethod loadServiceMethod(Method method) {
//从缓存中获取,如果先前创建过久直接用
    //create中的eagerlyValidateMethods方法会提前创建对象并缓存
    ServiceMethod result = serviceMethodCache.get(method);
    if (result != null) return result;

    synchronized (serviceMethodCache) {
//防止多线程下已经创建缓存对象
      result = serviceMethodCache.get(method);
      if (result == null) {
      //建造模式创建对象
        result = ServiceMethod.parseAnnotations(this, method);
       //将解析完的对象放入缓存
        serviceMethodCache.put(method, result);
      }
    }
    return result;
  }

abstract class ServiceMethod {
  static  ServiceMethod parseAnnotations(Retrofit retrofit, Method method) {
    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);
    }
    if (returnType == void.class) {
      throw methodError(method, "Service methods cannot return void.");
    }

    return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
  }

  abstract @Nullable T invoke(Object[] args);
}
final class RequestFactory {
  static RequestFactory parseAnnotations(Retrofit retrofit, Method method) {
    return new Builder(retrofit, method).build();
  }

  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;
  }

  static final class Builder {
    // Upper and lower characters, digits, underscores, and hyphens, starting with a character.
    private static final String PARAM = "[a-zA-Z][a-zA-Z0-9_-]*";
    private static final Pattern PARAM_URL_REGEX = Pattern.compile("\\{(" + PARAM + ")\\}");
    private static final Pattern PARAM_NAME_REGEX = Pattern.compile(PARAM);

    final Retrofit retrofit;
    final Method method;
    final Annotation[] methodAnnotations;
    final Annotation[][] parameterAnnotationsArray;
    final Type[] parameterTypes;

    boolean gotField;
    boolean gotPart;
    boolean gotBody;
    boolean gotPath;
    boolean gotQuery;
    boolean gotQueryName;
    boolean gotQueryMap;
    boolean gotUrl;
    @Nullable String httpMethod;
    boolean hasBody;
    boolean isFormEncoded;
    boolean isMultipart;
    @Nullable String relativeUrl;
    @Nullable Headers headers;
    @Nullable MediaType contentType;
    @Nullable Set relativeUrlParamNames;
    @Nullable ParameterHandler[] parameterHandlers;
    boolean isKotlinSuspendFunction;

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

    RequestFactory build() {
    //解析带注释的方法
      for (Annotation annotation : methodAnnotations) {
        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 build() { //解析带注释的方法
      for (Annotation annotation : methodAnnotations) {
        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);
    }
    //解析带注释的具体方法
    private void parseMethodAnnotation(Annotation annotation) {
      if (annotation instanceof DELETE) {
        parseHttpMethodAndPath("DELETE", ((DELETE) annotation).value(), false);
      } else if (annotation instanceof GET) {
        parseHttpMethodAndPath("GET", ((GET) annotation).value(), false);
      } else if (annotation instanceof HEAD) {
        parseHttpMethodAndPath("HEAD", ((HEAD) annotation).value(), false);
      } else if (annotation instanceof PATCH) {
        parseHttpMethodAndPath("PATCH", ((PATCH) annotation).value(), true);
      } else if (annotation instanceof POST) {
        parseHttpMethodAndPath("POST", ((POST) annotation).value(), true);
      } else if (annotation instanceof PUT) {
        parseHttpMethodAndPath("PUT", ((PUT) annotation).value(), true);
      } else if (annotation instanceof OPTIONS) {
        parseHttpMethodAndPath("OPTIONS", ((OPTIONS) annotation).value(), false);
      } else if (annotation instanceof HTTP) {
        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);
      } 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;
      }
    }

从上面的代码中,loadServiceMethod方法,中调用了ServiceMethod.parseAnnotations方法,在这个方法中通过RequestFactory类解析了所有的自定义类中的带注释的方法,且遍历该方法的中的所有注释进行解析,解析完完成后,嗲用RequestFactory的build方法,创建RequestFactory,
接下来我们来看ServiceMethod.parseAnnotations的return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory)方法。

  static  HttpServiceMethod 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的方法,如果是对方法进行处理
      Type[] parameterTypes = method.getGenericParameterTypes();
      Type responseType = Utils.getParameterLowerBound(0,
          (ParameterizedType) parameterTypes[parameterTypes.length - 1]);
      if (getRawType(responseType) == Response.class && responseType instanceof ParameterizedType) {
        // Unwrap the actual body type from Response.
        responseType = Utils.getParameterUpperBound(0, (ParameterizedType) responseType);
        continuationWantsResponse = true;
      } else {
        // TODO figure out if type is nullable or not
        // Metadata metadata = method.getDeclaringClass().getAnnotation(Metadata.class)
        // Find the entry for method
        // Determine if return type is nullable or not
      }

      adapterType = new Utils.ParameterizedTypeImpl(null, Call.class, responseType);
      annotations = SkipCallbackExecutorImpl.ensurePresent(annotations);
    } else {
      adapterType = method.getGenericReturnType();//获取java方法的返回类型
    }

    CallAdapter callAdapter =
        createCallAdapter(retrofit, method, adapterType, annotations);
    Type responseType = callAdapter.responseType();
  //异常判断
    if (responseType == okhttp3.Response.class) {
      throw methodError(method, "'"
          + getRawType(responseType).getName()
          + "' is not a valid response body type. Did you mean ResponseBody?");
    }
    if (responseType == Response.class) {
      throw methodError(method, "Response must include generic type (e.g., Response)");
    }
    // TODO support Unit for Kotlin?
    if (requestFactory.httpMethod.equals("HEAD") && !Void.class.equals(responseType)) {
      throw methodError(method, "HEAD method must use Void as response type.");
    }

    Converter responseConverter =
        createResponseConverter(retrofit, method, responseType);

    okhttp3.Call.Factory callFactory = retrofit.callFactory;//创建一个OkHttp对象
    if (!isKotlinSuspendFunction) {
      return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
    } else if (continuationWantsResponse) {
      //noinspection unchecked Kotlin compiler guarantees ReturnT to be Object.
      return (HttpServiceMethod) new SuspendForResponse<>(requestFactory,
          callFactory, responseConverter, (CallAdapter>) callAdapter);
    } else {
      //noinspection unchecked Kotlin compiler guarantees ReturnT to be Object.
      return (HttpServiceMethod) new SuspendForBody<>(requestFactory,
          callFactory, responseConverter, (CallAdapter>) callAdapter,
          continuationBodyNullable);
    }
  }

HttpServiceMethod ->CallAdapter
  private static  CallAdapter createCallAdapter(
      Retrofit retrofit, Method method, Type returnType, Annotation[] annotations) {
    try {
      //noinspection unchecked
 //通过retrofit的callAdapter方法返回的
      return (CallAdapter) 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);
  }

Retrofit->nextCallAdapter
  public CallAdapter nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType,
      Annotation[] annotations) {
    checkNotNull(returnType, "returnType == null");
    checkNotNull(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) {
        return adapter;
      }
    }

    StringBuilder builder = new StringBuilder("Could not locate call adapter for ")
        .append(returnType)
        .append(".\n");
    if (skipPast != null) {
      builder.append("  Skipped:");
      for (int i = 0; i < start; i++) {
        builder.append("\n   * ").append(callAdapterFactories.get(i).getClass().getName());
      }
      builder.append('\n');
    }
    builder.append("  Tried:");
    for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
      builder.append("\n   * ").append(callAdapterFactories.get(i).getClass().getName());
    }
    throw new IllegalArgumentException(builder.toString());
  }


HttpServiceMethod->Converter
  private static  Converter createResponseConverter(
      Retrofit retrofit, Method method, Type responseType) {
    Annotation[] annotations = method.getAnnotations();
    try {
      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  Converter responseBodyConverter(Type type, Annotation[] annotations) {
    return nextResponseBodyConverter(null, type, annotations);
  }


Retrofit->nextResponseBodyConverter
  public  Converter nextResponseBodyConverter(
      @Nullable Converter.Factory skipPast, Type type, Annotation[] annotations) {
    checkNotNull(type, "type == null");
    checkNotNull(annotations, "annotations == null");

    int start = converterFactories.indexOf(skipPast) + 1;
    for (int i = start, count = converterFactories.size(); i < count; i++) {
//默认的数据转换器BuiltInConverters,如果接口方法返回值类型不是ResponseBody和Void的话,返回null
    //分析的这个例子中,接口方法返回值的泛型是HttpResult,所以会循环到下个GsonConverterFactor对象
      Converter converter =
          converterFactories.get(i).responseBodyConverter(type, annotations, this);
      if (converter != null) {
        //noinspection unchecked
        return (Converter) converter;
      }
    }

    StringBuilder builder = new StringBuilder("Could not locate ResponseBody converter for ")
        .append(type)
        .append(".\n");
    if (skipPast != null) {
      builder.append("  Skipped:");
      for (int i = 0; i < start; i++) {
        builder.append("\n   * ").append(converterFactories.get(i).getClass().getName());
      }
      builder.append('\n');
    }
    builder.append("  Tried:");
    for (int i = start, count = converterFactories.size(); i < count; i++) {
      builder.append("\n   * ").append(converterFactories.get(i).getClass().getName());
    }
    throw new IllegalArgumentException(builder.toString());
  }

从上面的代码中看到最后在Retrofit->nextCallAdapter,获取在Retrofit进行build时,创建的CallAdaptaer对象,然后在获取converterFactories的转换器集合对象,在最后在创建HttpServiceMethod对象

然后我们回到create方法中,返回了一个动态代理的对象,真正处理代码的是在动态代理的invoke方法。接着我们来查看invoke方法

  HttpServiceMethod->invoke

  @Override final @Nullable ReturnT invoke(Object[] args) {
    Call call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
    return adapt(call, args);
  }

protected abstract @Nullable ReturnT adapt(Call call, Object[] args);

  static final class CallAdapted extends HttpServiceMethod {
    private final CallAdapter callAdapter;

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

    @Override protected ReturnT adapt(Call call, Object[] args) {
      return callAdapter.adapt(call);
    }
  }

我们看到在invoke方法中,用调用了callAdapter.adapt(方法)

这个CallAdapter实际上是从DefaultCallAdapterFactory中的get方法中获取详见 HttpServiceMethod方法的CallAdapter adapter = callAdapterFactories.get(i).get(returnType, annotations, this);代码

final class DefaultCallAdapterFactory extends CallAdapter.Factory {
  private final @Nullable Executor callbackExecutor;

  DefaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
    this.callbackExecutor = callbackExecutor;
  }

  @Override public @Nullable CallAdapter get(
      Type returnType, Annotation[] annotations, Retrofit retrofit) {
    if (getRawType(returnType) != Call.class) {
      return null;
    }
    if (!(returnType instanceof ParameterizedType)) {
      throw new IllegalArgumentException(
          "Call return type must be parameterized as Call or Call");
    }
    final Type responseType = Utils.getParameterUpperBound(0, (ParameterizedType) returnType);

    final Executor executor = Utils.isAnnotationPresent(annotations, SkipCallbackExecutor.class)
        ? null
        : callbackExecutor;

    return new CallAdapter>() {
      @Override public Type responseType() {
        return responseType;
      }

      @Override public Call adapt(Call call) {
        return executor == null
            ? call
            : new ExecutorCallbackCall<>(executor, call);
      }
    };
  }

  static final class ExecutorCallbackCall implements Call {
    final Executor callbackExecutor;
    final Call delegate;

    ExecutorCallbackCall(Executor callbackExecutor, Call delegate) {
      this.callbackExecutor = callbackExecutor;
      this.delegate = delegate;
    }

    @Override public void enqueue(final Callback callback) {
      checkNotNull(callback, "callback == null");

      delegate.enqueue(new Callback() {
        @Override public void onResponse(Call call, final Response response) {
          callbackExecutor.execute(new Runnable() {
            @Override public void run() {
              if (delegate.isCanceled()) {
                // Emulate OkHttp's behavior of throwing/delivering an IOException on cancellation.
                callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled"));
              } else {
                callback.onResponse(ExecutorCallbackCall.this, response);
              }
            }
          });
        }

        @Override public void onFailure(Call call, final Throwable t) {
          callbackExecutor.execute(new Runnable() {
            @Override public void run() {
              callback.onFailure(ExecutorCallbackCall.this, t);
            }
          });
        }
      });
    }

    @Override public boolean isExecuted() {
      return delegate.isExecuted();
    }

    @Override public Response execute() throws IOException {
      return delegate.execute();
    }

    @Override public void cancel() {
      delegate.cancel();
    }

    @Override public boolean isCanceled() {
      return delegate.isCanceled();
    }

    @SuppressWarnings("CloneDoesntCallSuperClone") // Performing deep clone.
    @Override public Call clone() {
      return new ExecutorCallbackCall<>(callbackExecutor, delegate.clone());
    }

    @Override public Request request() {
      return delegate.request();
    }
  }
}
 
 

上面的源代码有三点需要注意
1:看那个get(),就是这里返回了我起调函数的那个callAdapter,所以adapt(),执行的就是

@Override public Call adapt(Call call) {
        return new ExecutorCallbackCall<>(callbackExecutor, call);
      }
 
 

2这里面还有一个CallbackExecutor,这个是在retrofit构建时候传入的,Android平台默认为MainThreadExecutor

  static class MainThreadExecutor implements Executor {
      private final Handler handler = new Handler(Looper.getMainLooper());

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

这里使用了典型的代理模式,不过这次是静态代理。ExecutorCallbackCall 代理了OkHttpCall,他们都实现了接口Call。

至此create方法算是看完了

发起请求enqueue

接下来我们看retrofit2的OkHttpCall中的enqueue方法

  @Override public void enqueue(final 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 = rawCall = createRawCall();//注意这里
        } catch (Throwable t) {
          throwIfFatal(t);
          failure = creationFailure = t;
        }
      }
    }

    if (failure != null) {
      callback.onFailure(this, failure);
      return;
    }

    if (canceled) {
      call.cancel();
    }
 //真正发起异步请求的地方,这个call是okhttp的call
    call.enqueue(new okhttp3.Callback() {
      @Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
        Response response;
        try {
          response = parseResponse(rawResponse);//关键代码
        } catch (Throwable e) {
          throwIfFatal(e);
          callFailure(e);
          return;
        }

        try {
          callback.onResponse(OkHttpCall.this, response);
        } catch (Throwable t) {
          throwIfFatal(t);
          t.printStackTrace(); // TODO this is not great
        }
      }

      @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) {
          throwIfFatal(t);
          t.printStackTrace(); // TODO this is not great
        }
      }
    });
  }

代码比较简单,我么我一看到代码中,先通过createRawCall方法创建Call对象,然后调用call.enqueue发起真正的请求,最后在通过parseResponse(rawResponse)解析返回的response方法
我们先来看createRawCall方法

  private okhttp3.Call createRawCall() throws IOException {
    okhttp3.Call call = callFactory.newCall(requestFactory.create(args));
    if (call == null) {
      throw new NullPointerException("Call.Factory returned null.");
    }
    return call;
  }

RequestFactory->create
  okhttp3.Request create(Object[] args) throws IOException {
    @SuppressWarnings("unchecked") // It is an error to invoke a method with the wrong arg types.
    ParameterHandler[] handlers = (ParameterHandler[]) parameterHandlers;

    int argumentCount = args.length;
    if (argumentCount != handlers.length) {
      throw new IllegalArgumentException("Argument count (" + argumentCount
          + ") doesn't match expected count (" + handlers.length + ")");
    }

    RequestBuilder requestBuilder = new RequestBuilder(httpMethod, baseUrl, relativeUrl,
        headers, contentType, hasBody, isFormEncoded, isMultipart);

    if (isKotlinSuspendFunction) {
      // The Continuation is the last parameter and the handlers array contains null at that index.
      argumentCount--;
    }

    List argumentList = new ArrayList<>(argumentCount);
    for (int p = 0; p < argumentCount; p++) {
      argumentList.add(args[p]);
      handlers[p].apply(requestBuilder, args[p]);
    }

    return requestBuilder.get()
        .tag(Invocation.class, new Invocation(method, argumentList))
        .build();
  }

 
 

我们知道要创建一个okhtt3.call,需要使用okhttp的Call.Factory.newCall(Request r)的方法,那个callFactory就是我们的工厂,而Request是由RequestFactory.create()的方法创建的,create方法可以说是至关重要,我们前面搞来搞去就是为了能生成一个okhttp3的一个Request。
然后我们接着看parseResponse(rawResponse)方法

  Response 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();//这里与okhttp3一样,将返回值封装成一个Response对象

    int code = rawResponse.code();
    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();
      }
    }

    if (code == 204 || code == 205) {//返回204 205
      rawBody.close();
      return Response.success(null, rawResponse);
    }

    ExceptionCatchingResponseBody catchingBody = new ExceptionCatchingResponseBody(rawBody);//关键代码
    try {
      T body = responseConverter.convert(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;
    }
  }
  OkHttpCall->ExceptionCatchingResponseBody 
  static final class ExceptionCatchingResponseBody extends ResponseBody {
    private final ResponseBody delegate;
    private final BufferedSource delegateSource;
    @Nullable IOException thrownException;

    ExceptionCatchingResponseBody(ResponseBody delegate) {
      this.delegate = delegate;
      this.delegateSource = Okio.buffer(new ForwardingSource(delegate.source()) {
        @Override public long read(Buffer sink, long byteCount) throws IOException {
          try {
            return super.read(sink, byteCount);
          } catch (IOException e) {
            thrownException = e;
            throw e;
          }
        }
      });
    }

    @Override public MediaType contentType() {
      return delegate.contentType();
    }

    @Override public long contentLength() {
      return delegate.contentLength();
    }

    @Override public BufferedSource source() {
      return delegateSource;
    }

    @Override public void close() {
      delegate.close();
    }

    void throwIfCaught() throws IOException {
      if (thrownException != null) {
        throw thrownException;
      }
    }
  }

将返回的okhttp3的response解析为retrofit的response。关键是是通过responseConverter将返回数据解析成我们在接口声明文件中提供的数据类型,就是那个callAdapter里面的responseType(),其是由returnType得到的,而 returnType = method.getGenericReturnType();,就是我们声明时候的泛型类型。

总结:
Retrofit的代码请求部分都是基于OkHttp代码进行
先是创建了Retrofit的实例,与OkHttp一样,都是使用了建造者模式创建的,中间调用了网络请求工厂(okhttp3.Call.Factory),网络请求地址(HttpUrl),数据转换器(List),网络适配器(List),回调执行方法(Executor)
在create方法中接口方法的返回值是网络适配器返回对象,类型要和接口方法的返回值一致。动态代理的invoke方法里,通过Retrofit的配置和接口方法的注解配置生成ServiceMethod对象,这个对象保存了网络请求的所有配置。大部分方法和解析注解生成配置有关,主要关注两个方法:一个toRequest通过RequestBuilder生成OKhttp的Request,toResponse可以利用数据转换器将ResponseBody转为请求接口方法返回值泛型。这两个方法都是给OkHttpCall使用。再通过ServiceMethod创建了OkHttpCall,里面有请求网络的方法,实际上是根据ServiceMethod的配置网络信息生成的Request再生成okhttp3.Call,将请求结果通过ServiceMethod的配置转换器进行数据转换,最终回调给调用它的类(默认ExecutorCallbackCall),在动态代理的invoke方法里,创建ServiceMethod时用get方法生成适配器后,再通过适配器的adapt生成ExecutorCallbackCall返回值,ExecutorCallbackCall中用静态代理模式实现,被代理对象是OkHttpCall。最后在对返回的对象进行解析,可以通过使用GsonConverterFactory的具体转换结果类型,是在创建ServiceMethod时,这个是用解析的接口方法中的返回值泛型确定的。

你可能感兴趣的:(Android Retrofit的应用及源码解析)