美文网首页
Retrofit源码解读

Retrofit源码解读

作者: 小川君 | 来源:发表于2018-03-22 19:39 被阅读0次

    前言

    网络请求作为Android开发中不可获取的一部分,一直都扮演着十分重要的角色;从最初的HttpClient、HttpUrlConnection到xUtils、Async Http、Volley再到现在的Retrofit,网络请求的框架一直都是不断的向前演变着;后续的我会继续把没有涉及到的网络请求框架的源码补写上,作为一个小白,能做的就是看些源码然后做做笔记,自己的笔记可能只有自己看得懂,也有可能是自己看不懂的就选择性的跳过去了,总之以后会继续优化这几篇源码文章。

    优点
    优点
    支持同步&异步 支持多种数据的解析& 序列化格式 (Json xml Gson) 支持RxJava 采用注解配置网路请求参数 &运用大量的设计模式 简化使用 高度封装 彻底解耦 而且扩展性也很好 基于OkHttp &遵循Restful风格

    配置

    public class RetrofitClient {
        private Retrofit mRetrofit;
        private RestService mService;
    
        public RetrofitClient(String BASE_URL){
            mRetrofit = new Retrofit.Builder()
                    .baseUrl(BASE_URL)
                    // 使用Gson响应数据解析器工厂
                    .addConverterFactory(GsonConverterFactory.create())
                    // 使用RxJava网络请求适配器工厂
                    .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                    .build();
            mService = mRetrofit.create(RestService.class);
        }
    
        public RestService getRestService(){
            if(mService != null){
                return mService;
            }
            return null;
        }
    
    }
    

    通过builder模式创建配置Retrofit对象,Retrofit不是一个单例,但是我们可以将Retrofit的实例化放在全局当中,避免创建过多的对象。
    我们先来分析下Retrofit.Builder:

        /**
         * 平台类型
         */
        private final Platform platform;
        /**
          *网络请求器的工厂  用于生产网络请求器(Call)
          */
        private @Nullable okhttp3.Call.Factory callFactory;
       /**
         *  网络请求的url地址
         */
        private HttpUrl baseUrl;
          /**
            * 数据转换器工厂的集合 主要是解析数据
            *如果你在外面传入了一个新的 这个集合就会有两个 其实一般也就这两个 当然也可以继续传
            */  
        private final List<Converter.Factory> converterFactories = new ArrayList<>();
       /**
       * 网络请求适配器工厂的集合  网络请求适配器工厂用于生产网络请求适配器CallAdapter
       * 配合网络请求器,执行发起请求,以及对结果进行回调 
       */
        private final List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>();
     /**
         *回调方法执行器  如果当前操作系统是Android系统  会创建一个位于主线程的handler对象
         */
        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;
    
          converterFactories.addAll(retrofit.converterFactories);
          // Remove the default BuiltInConverters instance added by build().
          converterFactories.remove(0);
    
          callAdapterFactories.addAll(retrofit.callAdapterFactories);
          // Remove the default, platform-aware call adapter added by build().
          callAdapterFactories.remove(callAdapterFactories.size() - 1);
    
          callbackExecutor = retrofit.callbackExecutor;
          validateEagerly = retrofit.validateEagerly;
        }
    
    

    以上是Builder中的参数与构造方法 Builder中的所有参数最后都会传给Retrofit 所以相应的在Retrofit中也有一份相同的参数 下面就不在介绍了
    构造器Builder(Retrofit)是在新版本添加的 2.0的时候还没有 这里也不过多的赘述 ,一般情况下我们都是调用的参数为空的构造器 我们就从这里开始一步步解析Retrofit。

    class Platform {
      private static final Platform PLATFORM = findPlatform();
    
      static Platform get() {
        return PLATFORM;
      }
    
      private static Platform findPlatform() {
        try {
          Class.forName("android.os.Build");
          if (Build.VERSION.SDK_INT != 0) {
            return new Android();
          }
        } catch (ClassNotFoundException ignored) {
        }
        try {
          Class.forName("java.util.Optional");
          return new Java8();
        } catch (ClassNotFoundException ignored) {
        }
        return new Platform();
      }
    
      @Nullable Executor defaultCallbackExecutor() {
        return null;
      }
    
      CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
        if (callbackExecutor != null) {
          return new ExecutorCallAdapterFactory(callbackExecutor);
        }
        return DefaultCallAdapterFactory.INSTANCE;
      }
    
      boolean isDefaultMethod(Method method) {
        return false;
      }
    
    

    这个是Platform类,返回两个子类Java8、Android以及当前对象,我这里以Android为例:

    
        @Override public Executor defaultCallbackExecutor() {
          /**
           * 创建一个位于主线程的handler对象
           */
          return new MainThreadExecutor();
        }
    
        /**
         *创建默认的网络请求适配器工厂
         *该默认工厂生产的 adapter 会使得Call在异步调用时在指定的 Executor 上执行回调
         *在Retrofit中提供了几种CallAdapterFactory: ExecutorCallAdapterFactory(默认)、GuavaCallAdapterFactory、Java8CallAdapterFactory、RxJavaCallAdapterFactory、DefaultCallAdapterFactory
         *采用了策略模式
         * @param callbackExecutor
         * @return
         */
        @Override CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
          if (callbackExecutor == null) throw new AssertionError();
          return new ExecutorCallAdapterFactory(callbackExecutor);
        }
    
        /**
          * 主线程中的handler
          */
        static class MainThreadExecutor implements Executor {
          private final Handler handler = new Handler(Looper.getMainLooper());
    
          @Override public void execute(Runnable r) {
            handler.post(r);
          }
        }
      }
    

    Android类中的defaultCallbackExecutor方法创建并返回了一个回调方法执行器,里面有一个主线程的handler负责接收处理消息
    defaultCallAdapterFactory方法则创建了一个默认的网络请求适配器工厂ExecutorCallAdapterFactory,网络请求适配器(CallAadpter)是做什么的呢 他有两点作用,一个是检查返回值类型,而返回值类型是由网络请求适配器工厂设置的,这个接口Retrofit暴露了出来,开发者可以根据自己的需要封装或者使用RxJava的网络请求适配器工厂,进去来设置网络请求的返回值类型,以ExecutorCallAdapterFactory 为例:

    
    final class ExecutorCallAdapterFactory extends CallAdapter.Factory {
      final Executor callbackExecutor;
    
      ExecutorCallAdapterFactory(Executor callbackExecutor) {
        this.callbackExecutor = callbackExecutor;
      }
    
      @Override
      public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
        if (getRawType(returnType) != Call.class) {
          return null;
        }
        final Type responseType = Utils.getCallResponseType(returnType);
        return new CallAdapter<Object, Call<?>>() {
          @Override public Type responseType() {
            return responseType;
          }
    
          /**
           * 会使得Call在异步调用时在指定的 Executor 上执行回调
           * @param call
           * @return
           */
          @Override public Call<Object> adapt(Call<Object> call) {
            return new ExecutorCallbackCall<>(callbackExecutor, 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");
    
          // 这里将请求交给okhttpClient 处理    并将响应交给callbackExecutor发送到主线程   来处理
          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();
        }
    
      }
    

    以上两个类的代码就是网络请求适配器工厂通过判断是它指定的返回值类型就会创建一个网络请求适配器,提前透露一些,这个网络请求适配器会拿着我们前面在builder中创建的主线程的回调执行器和OkhttpClient在ExecutorCallbackCall类中的enqueue(异步)和execute(同步)进行网络请求 了,如果是异步的话,会通过主线程的回调执行器将结果返回到主线程。这就是网络请求适配器的作用;ok,这个横向铺展的有点太大,我们回到Platform中。
    现在我们知道Platfrom.get()返回的是Android对象,Retrofit.Builder的构造器到这就没了,Builder对一些重要的参数都提供的入参接口,以便开发者能够更好的扩展,比如:okhttp3.Call.Factory 网络请求器工厂、Executor回调方法执行器、List<Converter.Factory>服务器响应数据转换器、List<CallAdapter.Factory>网络请求适配器,当然没有传也没关系,都有默认的实现,当然请求地址的Host还是要必传的。
    下面就是builde(),用来创建Retrofit的方法:

    public Retrofit build() {
          if (baseUrl == null) {
            throw new IllegalStateException("Base URL required.");
          }
        // 网络请求执行器 默认okhttp  
          okhttp3.Call.Factory callFactory = this.callFactory;
          if (callFactory == null) {
            callFactory = new OkHttpClient();
          }
         // 主线程回到方法执行器
          Executor callbackExecutor = this.callbackExecutor;
          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);
          callAdapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
    
          // Make a defensive copy of the converters.
    //响应数据
          List<Converter.Factory> converterFactories =
              new ArrayList<>(1 + this.converterFactories.size());
    
          // 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);
    
          return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
              unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
        }
    

    三个地方

    callbackExecutor = platform.defaultCallbackExecutor();
    调用Android类中的defaultCallbackExecutor方法

     @Override public Executor defaultCallbackExecutor() {
          /**
           * 创建一个位于主线程的handler对象
           */
          return new MainThreadExecutor();
        }
    

    添加默认的网络请求适配器工厂
    callAdapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
    调用Android类中的defaultCallAdapterFactory方法

     @Override CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
          if (callbackExecutor == null) throw new AssertionError();
          return new ExecutorCallAdapterFactory(callbackExecutor);
        }
    

    添加默认的响应数据解析工厂
    converterFactories.add(new BuiltInConverters()) 这里我们以com.squareup.retrofit2:converter-gson包中的Gson解析器为例GsonConverterFactory,后面再说。
    最后就是调用了new Retrofit()创建Retrofit对象。

    Retrofit的入口就是create()方法:

      public <T> T create(final Class<T> service) {
        Utils.validateServiceInterface(service);
        if (validateEagerly) {
          eagerlyValidateMethods(service);
        }
        return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
            new InvocationHandler() {
              /**
               * 选择平台 Android or Java 以{@link Platform.Android#defaultCallbackExecutor()}为例 会创建一个位于主线程的handler对象
               * {@link retrofit2.Platform.Android#defaultCallAdapterFactory(Executor)}会返回一个CallAdapter.Factory对象
               * 具体的后面再说
               */
              private final Platform platform = Platform.get();
    
              @Override public Object invoke(Object proxy, Method method, @Nullable Object[] args)
                  throws Throwable {
                // If the method is a method from Object then defer to normal invocation.
                if (method.getDeclaringClass() == Object.class) {
                  return method.invoke(this, args);
                }
                // 恒为false
                if (platform.isDefaultMethod(method)) {
                  return platform.invokeDefaultMethod(method, service, proxy, args);
                }
                //  解析ServiceApi接口中的方法  并返回一个serviceMethod对象
                ServiceMethod<Object, Object> serviceMethod =
                    (ServiceMethod<Object, Object>) loadServiceMethod(method);
                OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
               
                return serviceMethod.adapt(okHttpCall);
              }
            });
      }
    

    首先是检查传入的class对象是否是接口类型的 如果不是就是抛出异常
    然后就是对注解类型的校验,默认为false 可以手动修改 我们可以进入这个方法去看看

    
      private void eagerlyValidateMethods(Class<?> service) {
        Platform platform = Platform.get();
        for (Method method : service.getDeclaredMethods()) {
          if (!platform.isDefaultMethod(method)) {
            loadServiceMethod(method);
          }
        }
      }
    
      ServiceMethod<?, ?> loadServiceMethod(Method method) {
        // 如果缓存中有 就返回 如果没有 就通过构建者模式的创建一个ServiceMethod  并将ServiceMethod放入到serviceMethodCache缓存中
        ServiceMethod<?, ?> result = serviceMethodCache.get(method);
        if (result != null) return result;
    
        synchronized (serviceMethodCache) {
          result = serviceMethodCache.get(method);
          if (result == null) {
            result = new ServiceMethod.Builder<>(this, method).build();
            serviceMethodCache.put(method, result);
          }
        }
        return result;
      }
    

    首先拿到这个接口的所有方法 然后逐一判断是否在serviceMethodCache缓存中有与之对应的ServiceMethod 如果有直接返回到 如果没有就创建一个新的 然后加入缓存;
    这里的ServiceMethod中会储存方法的所有属性 包括入参注解 、返回值类型 、请求路径、请求头等等,可以说ServiceMethod就是负责将接口方法转换成完整请求,并通过他来发送请求的工具类。

    回到create(),最后返回了一个动态代理对象,因为接口是无法直接调用方法的,我们在客户端拿到这个对象之后就可以直接调用响应的方法进行请求了。
    我们来看这个动态代理

    Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
            new InvocationHandler() {
              /**
               * 选择平台 Android or Java 以{@link Platform.Android#defaultCallbackExecutor()}为例 会创建一个位于主线程的handler对象
               * {@link retrofit2.Platform.Android#defaultCallAdapterFactory(Executor)}会返回一个CallAdapter.Factory对象
               * 具体的后面再说
               */
              private final Platform platform = Platform.get();
    
              @Override public Object invoke(Object proxy, Method method, @Nullable Object[] args)
                  throws Throwable {
                // If the method is a method from Object then defer to normal invocation.
                if (method.getDeclaringClass() == Object.class) {
                  return method.invoke(this, args);
                }
                // 恒为false
                if (platform.isDefaultMethod(method)) {
                  return platform.invokeDefaultMethod(method, service, proxy, args);
                }
                //  解析ServiceApi接口中的方法  并返回一个serviceMethod对象
                ServiceMethod<Object, Object> serviceMethod =
                    (ServiceMethod<Object, Object>) loadServiceMethod(method);
                OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
           
                return serviceMethod.adapt(okHttpCall);
              }
            });
    

    JVM在编译的时候会自动生成我们的API接口代理类,并遍历里面的所有方法然后交给InvocationHandler,我们在客户端每次在调用相应的方法的时候 就会通过解析这个方法最后在InvocationHandler调用相应的method.invoke();当然在这里我们是需要将方法转换成接口然后发送出去的,所以Retrofit又封装了一个新的返回值。
    我们主要看这三行代码:

    //  解析ServiceApi接口中的方法  并返回一个serviceMethod对象
                ServiceMethod<Object, Object> serviceMethod =
                    (ServiceMethod<Object, Object>) loadServiceMethod(method);
                OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
          
                return serviceMethod.adapt(okHttpCall);
    

    首先去解析我们在客户端调用的方法,loadServiceMethod()上面我们有说过,会从缓存中获取一个ServiceMethod对象,如果没有 就会新建一个
    第二行,创建一个okHttpCall对象
    第三个调用ServiceMethod的adapt方法 开始发送请求,我们进去看看

      T adapt(Call<R> call) {
        return callAdapter.adapt(call);
      }
    

    通过callAdapter调用了adapt方法,我前面有说过网络请求适配器工厂除了默认的可能还会有自己扩展加入的,我们这里以默认的为例来分析,分析之前还要看看这个Retrofit是怎么拿到对应的callAdapterFactory的。在上面的ServiceMethod.Builder的build方法中 有两个地方还有说 现在说一下,就是CallAdapterFactory和ConverterAdapterFactory的获取使用

    
          // 创建请求适配器
          callAdapter = createCallAdapter();
          //  获取到返回值类型 响应类型
          responseType = callAdapter.responseType();
          if (responseType == Response.class || responseType == okhttp3.Response.class) {
            throw methodError("'"
                + Utils.getRawType(responseType).getName()
                + "' is not a valid response body type. Did you mean ResponseBody?");
          }
          // 获取数据转换器
          responseConverter = createResponseConverter();
        //  解析注解
          for (Annotation annotation : methodAnnotations) {
            parseMethodAnnotation(annotation);
          }
          // 去掉无关的代码
            ......
            ......
          return new ServiceMethod<>(this);
        }
    

    先来分享callAdapterFactory的创建

     private CallAdapter<T, R> createCallAdapter() {
          // 获取到method的返回值类型
          Type returnType = method.getGenericReturnType();
          if (Utils.hasUnresolvableType(returnType)) {
            throw methodError(
                "Method return type must not include a type variable or wildcard: %s", returnType);
          }
          if (returnType == void.class) {
            throw methodError("Service methods cannot return void.");
          }
          //  获取到method的注解类型
          Annotation[] annotations = method.getAnnotations();
          try {
            //noinspection unchecked
            // 通过返回值和注解类型 得到一个CallAdapter对象
            return (CallAdapter<T, R>) retrofit.callAdapter(returnType, annotations);
          } catch (RuntimeException e) { // Wide exception range because factories are user code.
            throw methodError(e, "Unable to create call adapter for %s", returnType);
          }
        }
    

    根据调用方法的注解类型和返回值类型 去调用Retrofit中的callAdapter方法 并返回一个CallAdapter对象,最后会到nextCallAdapter()

     public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType,
          Annotation[] annotations) {
        checkNotNull(returnType, "returnType == null");
        checkNotNull(annotations, "annotations == null");
    
        /**
         * 第一次调用 skipPast = null  start = 0;  在builder构造器中会创建一个默认的CallAdapter.Factory并放入callAdapterFactories
         *
          */
    
        int start = callAdapterFactories.indexOf(skipPast) + 1;
        for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
          // 通过callAdapterFactory创建一个CallAdapter 并返回
          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());
      }
    

    这里假设集合里面有两个值分别是ExecutorCallAdapterFactory和RxJavaCallAdapterFactory,
    我们看下ExecutorCallAdapterFactory中的get()

    
        if (getRawType(returnType) != Call.class) {
          return null;
        }
        final Type responseType = Utils.getCallResponseType(returnType);
        return new CallAdapter<Object, Call<?>>() {
          @Override public Type responseType() {
            return responseType;
          }
    
          /**
           * 会使得Call在异步调用时在指定的 Executor 上执行回调
           * @param call
           * @return
           */
          @Override public Call<Object> adapt(Call<Object> call) {
            return new ExecutorCallbackCall<>(callbackExecutor, call);
          }
        };
      }
    

    这里有个判断 如果 返回值是Call类型的 就会new一个CallAdapter,相应的如果不是就会返回null;
    在Retrofit中的nextCallAdapter()中,如果返回了null就会进行下一个循环,如果不是null直接返回。我们再看下RxJavaCallAdapterFactory,逻辑是一样的,

    
        Class<?> rawType = getRawType(returnType);
        String canonicalName = rawType.getCanonicalName();
        boolean isSingle = "rx.Single".equals(canonicalName);
        boolean isCompletable = "rx.Completable".equals(canonicalName);
        if (rawType != Observable.class && !isSingle && !isCompletable) {
          return null;
        }
        if (!isCompletable && !(returnType instanceof ParameterizedType)) {
          String name = isSingle ? "Single" : "Observable";
          throw new IllegalStateException(name + " return type must be parameterized"
              + " as " + name + "<Foo> or " + name + "<? extends Foo>");
        }
    
        if (isCompletable) {
          // Add Completable-converter wrapper from a separate class. This defers classloading such that
          // regular Observable operation can be leveraged without relying on this unstable RxJava API.
          // Note that this has to be done separately since Completable doesn't have a parametrized
          // type.
          return CompletableHelper.createCallAdapter(scheduler);
        }
    
        CallAdapter<Observable<?>> callAdapter = getCallAdapter(returnType, scheduler);
        if (isSingle) {
          // Add Single-converter wrapper from a separate class. This defers classloading such that
          // regular Observable operation can be leveraged without relying on this unstable RxJava API.
          return SingleHelper.makeSingle(callAdapter);
        }
        return callAdapter;
      }
    

    如果返回值类型不是Observable类型的,就会返回null,是不是很清爽,回到ServiceMethod中,假设我们用的是ExecutorCallAdapterFactory,我们去看看其中的CallAdapter的adapt方法

       /**
           * 会使得Call在异步调用时在指定的 Executor 上执行回调
           * @param call
           * @return
           */
          @Override public Call<Object> adapt(Call<Object> call) {
            return new ExecutorCallbackCall<>(callbackExecutor, call);
          }
    

    还记不记得这个ExecutorCallAdapterFactory是在哪里实例化的么 是在Platform中,具体点就是Android类中 这个callbackExecutor就是创建了一个位于主线程的Handler对象,最后返回了Call的子类ExecutorCallbackCall,也就是我们API接口方法的返回值类型,附上客户端的调用代码:

    //        Call<MessageEntity> call = mRetrofitClient.getRestService().getMassageData("1104a8979299ece6412", "0d66327332878d1d61504caa72c4ae1a", "2.5.20", "a43e0c6d4484d6221293ba7d1b4f4bbb");
    //        call.enqueue(new Callback<MessageEntity>() {
    //            @Override
    //            public void onResponse(Call<MessageEntity> call, Response<MessageEntity> response) {
    //
    //            }
    //
    //            @Override
    //            public void onFailure(Call<MessageEntity> call, Throwable t) {
    //
    //            }
    //        });
    //        call.cancel();
    

    我们可以看到,在客户端我们通过call调用了异步方法enqueue,并回调到了主线程

    
      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");
    
          // 这里将请求交给okhttpClient 处理    并将响应交给callbackExecutor发送到主线程   来处理
          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();
        }
      
    

    再次附上ExecutorCallbackCall的实现;
    到这里Retrofit的请求的封装算是完成了,还有个小问题就是我们在ServiceMethod遗留的问题,响应数据适配器工厂的创建和响应数据适配器的调用,创建类似于网络请求适配工厂的创建,这里不再赘述,再来回顾下Retrofit中create方法:

    //  解析ServiceApi接口中的方法  并返回一个serviceMethod对象
                ServiceMethod<Object, Object> serviceMethod =
                    (ServiceMethod<Object, Object>) loadServiceMethod(method);
                OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
                
                return serviceMethod.adapt(okHttpCall);
    

    获取到一个ServiceMethod对象 然后通过这个对象获取到一个OkHttpCall对象,将这个OkHttpCall对象传入ServiceMethod中的adapt方法。这个OkHttpCall是什么,其实他就是Call,代表请求客户端,在ExecutorCallbackCall中调用异步请求的就是它, 我们以异步请求为例 来看下:

     @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.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) {
              t.printStackTrace();
            }
          }
    
          @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) {
              t.printStackTrace();
            }
          }
        });
      }
    

    在请求成功之后会调用parseResonse解析响应数据,解析成功之后会通过回调将数据发送出去,我们来看下解析

    
        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();
    
        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) {
          rawBody.close();
          return Response.success(null, rawResponse);
        }
    
        ExceptionCatchingRequestBody catchingBody = new ExceptionCatchingRequestBody(rawBody);
        try {
          T body = serviceMethod.toResponse(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;
        }
      }
    

    在最下面调用了ServiceMethod的toResonse方法,将响应body放进去

    R toResponse(ResponseBody body) throws IOException {
        return responseConverter.convert(body);
      }
    

    这里用到了我们的resonseConverter去解析响应体,我们以GsonConverterFactory为例:

     @Override public T convert(ResponseBody value) throws IOException {
        JsonReader jsonReader = gson.newJsonReader(value.charStream());
        try {
          return adapter.read(jsonReader);
        } finally {
          value.close();
        }
      }
    

    这个adapter是TypeAdapter类型的,通过gson.getAdapter(TypeToken.get(type))获取到,type是我们的返回值类型,最后将gson解析出来的读入到我们的返回值类型中 并返回。
    到此,整个Retrofit的源码的流程分析完毕。

    最后

    Retrofit的功能非常多的依赖Java反射,代码中其实还有很多细节,比如异常的捕获、抛出和处理、设计模式等等等等,这里就不多说了,希望大家也能去挖掘,读源码个人感觉收获还是蛮多的,从最片面的角度来看,最起码能发布源码的框架无论是代码设计亦或是代码健壮性都是值得学习的。

    相关文章

      网友评论

          本文标题:Retrofit源码解读

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