美文网首页
Android Retrofit的应用及源码解析

Android Retrofit的应用及源码解析

作者: 月影路西法 | 来源:发表于2020-04-06 19:41 被阅读0次

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

    下面是Retrofit的简单调用

    public interface RetrofitInterface {
        @GET
        Call getRetrofitGet(Map<String, Object> params);
    
        @POST
        Call getRetrofitPost(Map<String, Object> params);
    
        @PUT
        Call getRetrofitPut(Map<String, Object> params);
    
        @DELETE
        Call getRetrofitDelete(Map<String, Object> params);
    }
    
            Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl(url)
                    .build();
    
            RetrofitInterface retrofitInterface=retrofit.create(RetrofitInterface.class);
            Call<String> 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<String>() {
                @Override
                public void onResponse(Call<String> call, Response<String> response) {
                    String result=response.body().toString();
                    callBack.onSuccess(response.code(),result);
                }
    
                @Override
                public void onFailure(Call<String> 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<String,RequestBody>,可用于实现多文件上传
    @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<T> geResponse();//T为请求完成返回的ResponseBody
          //拼接完地址为http://192.168.0.1/url
    
        @POST("url/post") //post请求
          Call<ResponseBody> getPostResponse();
    
          @HTTP(method = "GET", path = "user/keys", hasBody = false)
          Call<ResponseBody> getHttpResponse();
    

    请求标记

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

    /**
             *表明是一个表单格式的请求(Content-Type:application/x-www-form-urlencoded)
             * <code>Field("username")</code> 表示将后面的 <code>String name</code> 中name的取值作为 username 的值
             */
            @POST("/form")
            @FormUrlEncoded
            Call<ResponseBody> 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<ResponseBody> testFileUpload1(@Part("name") RequestBody name, @Part("age") RequestBody age, @Part MultipartBody.Part file);
    

    网络请求参数

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

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

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

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

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

    • @Field 请求参数注解,提交请求的表单字段,必须要添加,而且需要配合@FormUrlEncoded使用,与get的Query一样
    • @FieldMap 请求参数注解,与@Field作用一致,用于不确定表单个数是传参数
          @FormUrlEncoded//请求格式注解,请求实体是一个From表单,每个键值对需要使用@File注解
         @POST("url/post") //post请求
          Call<ResponseBody> getPostResponse2(@Field ("id") int id, @Field ("username") String username);
    
    
          @FormUrlEncoded
         @POST("url/post") 
          Call<ResponseBody> getPostResponse3(@FieldMap Map<String, Object> 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<ResponseBody> 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} 就不适用了,所以文件只能用<b> @Part MultipartBody.Part </b>
             */
            @POST("/form")
            @Multipart
            Call<ResponseBody> testFileUpload2(@PartMap Map<String, RequestBody> args, @Part MultipartBody.Part file);
    
            @POST("/form")
            @Multipart
            Call<ResponseBody> testFileUpload3(@PartMap Map<String, RequestBody> args);
    

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

        @GET("url")
         Call<ResponseBody> 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<ResponseBody> geResponse3(@QueryMap Map<String, Object> 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<T> geResponse(@Path("userId") String userId);//T为请求完成返回的ResponseBody
          //拼接完地址为http://192.168.0.1/url/{userId} path指url中的可变参数
    

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

            @GET
            Call<ResponseBody> 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<Method, ServiceMethod<?>> serviceMethodCache = new ConcurrentHashMap<>();
     //okhttp工厂,真正发送交易的处理类
      final okhttp3.Call.Factory callFactory;
    //请求url前半部,基地址
      final HttpUrl baseUrl;
    //数据转换器工厂集
      final List<Converter.Factory> converterFactories;
    //网络请求适配器工厂集
      final List<CallAdapter.Factory> callAdapterFactories;
    //异步请求结果线程切换执行器
      final @Nullable Executor callbackExecutor;
    //标志位、是否马上解析接口方法
      final boolean validateEagerly;
    
      Retrofit(okhttp3.Call.Factory callFactory, HttpUrl baseUrl,
          List<Converter.Factory> converterFactories, List<CallAdapter.Factory> 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<Converter.Factory> converterFactories = new ArrayList<>();
    //网络请求适配器,如RxJava2CallAdapterFactory
        private final List<CallAdapter.Factory> 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<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
    //添加默认的网络适配器,也就是ExecutorCallAdapterFactory
          callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));
    // 与网络适配器的排序不同,默认的BuiltInConverters放在第一位,后面才是添加的
          // Make a defensive copy of the converters.
          List<Converter.Factory> 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<? extends CallAdapter.Factory> 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<? extends Converter.Factory> defaultConverterFactories() {
          return Build.VERSION.SDK_INT >= 24
              ? singletonList(OptionalConverterFactory.INSTANCE)
              : Collections.<Converter.Factory>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<String> 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<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
          Retrofit retrofit) {
        TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
        //返回对应的Converter对象
        return new GsonResponseBodyConverter<>(gson, adapter);
      }
    }
    
    final class GsonRequestBodyConverter<T> implements Converter<T, RequestBody> {
    
        @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> T create(final Class<T> 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<T> {
      static <T> ServiceMethod<T> 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<String> 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 <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的方法,如果是对方法进行处理
          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<T>.
            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<ResponseT, ReturnT> 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<String>)");
        }
        // 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<ResponseBody, ResponseT> 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<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);
        }
      }
    
    HttpServiceMethod ->CallAdapter
      private static <ResponseT, ReturnT> CallAdapter<ResponseT, ReturnT> createCallAdapter(
          Retrofit retrofit, Method method, Type returnType, Annotation[] annotations) {
        try {
          //noinspection unchecked
     //通过retrofit的callAdapter方法返回的
          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);
      }
    
    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 <ResponseT> Converter<ResponseBody, ResponseT> 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 <T> Converter<ResponseBody, T> responseBodyConverter(Type type, Annotation[] annotations) {
        return nextResponseBodyConverter(null, type, annotations);
      }
    
    
    Retrofit->nextResponseBodyConverter
      public <T> Converter<ResponseBody, T> 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<ResponseBody, ?> converter =
              converterFactories.get(i).responseBodyConverter(type, annotations, this);
          if (converter != null) {
            //noinspection unchecked
            return (Converter<ResponseBody, T>) 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<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
        return adapt(call, args);
      }
    
    protected abstract @Nullable ReturnT adapt(Call<ResponseT> call, Object[] args);
    
      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) {
          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<Foo> or Call<? extends Foo>");
        }
        final Type responseType = Utils.getParameterUpperBound(0, (ParameterizedType) returnType);
    
        final Executor executor = Utils.isAnnotationPresent(annotations, SkipCallbackExecutor.class)
            ? null
            : callbackExecutor;
    
        return new CallAdapter<Object, Call<?>>() {
          @Override public Type responseType() {
            return responseType;
          }
    
          @Override public Call<Object> adapt(Call<Object> call) {
            return executor == null
                ? call
                : new ExecutorCallbackCall<>(executor, call);
          }
        };
      }
    
      static final class ExecutorCallbackCall<T> implements Call<T> {
        final Executor callbackExecutor;
        final Call<T> delegate;
    
        ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) {
          this.callbackExecutor = callbackExecutor;
          this.delegate = delegate;
        }
    
        @Override public void enqueue(final Callback<T> callback) {
          checkNotNull(callback, "callback == null");
    
          delegate.enqueue(new Callback<T>() {
            @Override public void onResponse(Call<T> call, final Response<T> 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<T> 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<T> 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<T> clone() {
          return new ExecutorCallbackCall<>(callbackExecutor, delegate.clone());
        }
    
        @Override public Request request() {
          return delegate.request();
        }
      }
    }
    

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

    @Override public Call<Object> adapt(Call<Object> 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<T> 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<T> 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<Object>[] handlers = (ParameterHandler<Object>[]) 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<Object> 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<T> 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<Converter.Factory>),网络适配器(List<CallAdapter.Factory>),回调执行方法(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的应用及源码解析

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