美文网首页
retrofit源码解析(一)

retrofit源码解析(一)

作者: Fargo的狗窝 | 来源:发表于2017-09-29 00:02 被阅读0次

    用法:

    Introduction

    Retrofit turns your HTTP API into a Java interface.

    public interface GitHubService {
     @GET("users/{user}/repos")
     Call<List<Repo>> listRepos(@Path("user") String user);
    }
    The Retrofit class generates an implementation of the GitHubService >interface.
    
    
     Retrofit retrofit = new Retrofit.Builder()
       .baseUrl("https://api.github.com/")
       .build();
    
    GitHubService service = retrofit.create(GitHubService.class);```
    

    Each Call from the created GitHubService can make a synchronous or asynchronous HTTP request to the remote webserver.

    Call<List<Repo>> repos = service.listRepos("octocat");
    

    Use annotations to describe the HTTP request:

    首先,我们看下

    Retrofit retrofit = new Retrofit.Builder()
       .baseUrl("https://api.github.com/")
        .build();
    

    这段代码构建了一个Retrofit对象,让我们看看Builder的代码

     /**
       * Build a new {@link Retrofit}.
       * <p>
       * Calling {@link #baseUrl} is required before calling {@link #build()}. All other methods
       * are optional.
       */
      public static final class Builder {
        private final Platform platform;
        private @Nullable okhttp3.Call.Factory callFactory;
        private HttpUrl baseUrl;
        private final List<Converter.Factory> converterFactories = new ArrayList<>();
        private final List<CallAdapter.Factory> adapterFactories = new ArrayList<>();
        private @Nullable Executor callbackExecutor;
        private boolean validateEagerly;
    

    从builder注释中可以这段,在调用build()方法之前,必须设置baseurl

    童鞋们,从上面的代码有木有发现两个list

      private final List<Converter.Factory> converterFactories = new ArrayList<>();
        private final List<CallAdapter.Factory> adapterFactories = new ArrayList<>();
    

    辣么我们来看下

    /**
     * Convert objects to and from their representation in HTTP. Instances are created by {@linkplain
     * Factory a factory} which is {@linkplain Retrofit.Builder#addConverterFactory(Factory) installed}
     * into the {@link Retrofit} instance.
     */
    public interface Converter<F, T> {
      T convert(F value) throws IOException;
    
      /** Creates {@link Converter} instances based on a type and target usage. */
      abstract class Factory {
    

    哦,原来Converter<F, T>是将http请求返回结果由F类型转换为T类型
    而Converter.Factory是Converter的工厂类,

    辣么我们再看看另外一个

    **
     * Adapts a {@link Call} with response type {@code R} into the type of {@code T}. Instances are
     * created by {@linkplain Factory a factory} which is
     * {@linkplain Retrofit.Builder#addCallAdapterFactory(Factory) installed} into the {@link Retrofit}
     * instance.
     */
    public interface CallAdapter<R, T> {
      /**
       * Returns the value type that this adapter uses when converting the HTTP response body to a Java
       * object. For example, the response type for {@code Call<Repo>} is {@code Repo}. This type
       * is used to prepare the {@code call} passed to {@code #adapt}.
       * <p>
       * Note: This is typically not the same type as the {@code returnType} provided to this call
       * adapter's factory.
       */
      Type responseType();
    
      /**
       * Returns an instance of {@code T} which delegates to {@code call}.
       * <p>
       * For example, given an instance for a hypothetical utility, {@code Async}, this instance would
       * return a new {@code Async<R>} which invoked {@code call} when run.
       * <pre><code>
       * @Override
       * public <R> Async<R> adapt(final Call<R> call) {
       *   return Async.create(new Callable<Response<R>>() {
       *     @Override
       *     public Response<R> call() throws Exception {
       *       return call.execute();
       *     }
       *   });
       * }
       * </code></pre>
       */
      T adapt(Call<R> call);
    
      /**
       * Creates {@link CallAdapter} instances based on the return type of {@linkplain
       * Retrofit#create(Class) the service interface} methods.
       */
      abstract class Factory {
    

    哦,CallAdapter<R,T>是将Call<R> 转换成T(这就是rxjavaAdapter实现的接口)

    Retrofit retrofit = new Retrofit.Builder()
       .baseUrl("https://api.github.com/")
       .build();
    

    当我们使用Retrofit时,我们先
    然后我们看下Retrofit.Builder;

    
       Builder(Platform platform) {
          this.platform = platform;
          // 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());
        }
    
        public Builder() {
          this(Platform.get());
        }
    

    Builder的构造函数里,将一个BuiltInConverters add 到converterFactories,看注释我们可以知道,目的是为了防止被覆盖,前面我们知道Converters的作用是转换http请求结果,那么我们看下内置的BuiltInConverters是怎么样实现的

    final class BuiltInConverters extends Converter.Factory {
      @Override
      public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
          Retrofit retrofit) {
        if (type == ResponseBody.class) {
          return Utils.isAnnotationPresent(annotations, Streaming.class)
              ? StreamingResponseBodyConverter.INSTANCE
              : BufferingResponseBodyConverter.INSTANCE;
        }
        if (type == Void.class) {
          return VoidResponseBodyConverter.INSTANCE;
        }
        return null;
      }
    
      @Override
      public Converter<?, RequestBody> requestBodyConverter(Type type,
          Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
        if (RequestBody.class.isAssignableFrom(Utils.getRawType(type))) {
          return RequestBodyConverter.INSTANCE;
        }
        return null;
      }
    
      static final class VoidResponseBodyConverter implements Converter<ResponseBody, Void> {
        static final VoidResponseBodyConverter INSTANCE = new VoidResponseBodyConverter();
    
        @Override public Void convert(ResponseBody value) throws IOException {
          value.close();
          return null;
        }
      }
    
      static final class RequestBodyConverter implements Converter<RequestBody, RequestBody> {
        static final RequestBodyConverter INSTANCE = new RequestBodyConverter();
    
        @Override public RequestBody convert(RequestBody value) throws IOException {
          return value;
        }
      }
    
      static final class StreamingResponseBodyConverter
          implements Converter<ResponseBody, ResponseBody> {
        static final StreamingResponseBodyConverter INSTANCE = new StreamingResponseBodyConverter();
    
        @Override public ResponseBody convert(ResponseBody value) throws IOException {
          return value;
        }
      }
    
      static final class BufferingResponseBodyConverter
          implements Converter<ResponseBody, ResponseBody> {
        static final BufferingResponseBodyConverter INSTANCE = new BufferingResponseBodyConverter();
    
        @Override public ResponseBody convert(ResponseBody value) throws IOException {
          try {
            // Buffer the entire body to avoid future I/O.
            return Utils.buffer(value);
          } finally {
            value.close();
          }
        }
      }
    
      static final class ToStringConverter implements Converter<Object, String> {
        static final ToStringConverter INSTANCE = new ToStringConverter();
    
        @Override public String convert(Object value) {
          return value.toString();
        }
      }
    }
    

    Converter.Factory 有2个方法一个是responseBodyConverter 另一个是
    requestBodyConverter
    顾名思义responseBodyConverter,是转换http响应的,当type 是ResponseBody类型时返回结果有两种,一种是* StreamingResponseBodyConverter* 另一种是* BufferingResponseBodyConverter*
    当有注解@ Streaming的时候返回StreamingResponseBodyConverter,反之返回BufferingResponseBodyConverter;
    我们先看下StreamingResponseBodyConverter的实现

    static final class StreamingResponseBodyConverter
          implements Converter<ResponseBody, ResponseBody> {
        static final StreamingResponseBodyConverter INSTANCE = new StreamingResponseBodyConverter();
    
        @Override public ResponseBody convert(ResponseBody value) throws IOException {
          return value;
        }
      }
    

    我们可以看到,StreamingResponseBodyConverter的convert方法参数是ResponseBody类型,直接return value没有做任何操作;
    再看看

    static final class BufferingResponseBodyConverter
          implements Converter<ResponseBody, ResponseBody> {
        static final BufferingResponseBodyConverter INSTANCE = new BufferingResponseBodyConverter();
    
        @Override public ResponseBody convert(ResponseBody value) throws IOException {
          try {
            // Buffer the entire body to avoid future I/O.
            return Utils.buffer(value);
          } finally {
            value.close();
          }
        }
      }
    
    //Utils.java
    static ResponseBody buffer(final ResponseBody body) throws IOException {
        Buffer buffer = new Buffer();
        body.source().readAll(buffer);
        return ResponseBody.create(body.contentType(), body.contentLength(), buffer);
      }
    

    同样的BufferingResponseBodyConverter,convert函数参数是ResponseBody类型,返回也是ResponseBody类型,和BufferingResponseBodyConverter不同的是BufferingResponseBodyConverter将ResponseBody的流buffer下来再构建了一个新的ResponseBody;所以我们可以认为当type是ResponseBody类型的时候,BuiltInConverters对HTTP返回结果没有进行转换处理。
    那么我们来看看当type is Void

     static final class VoidResponseBodyConverter implements Converter<ResponseBody, Void> {
        static final VoidResponseBodyConverter INSTANCE = new VoidResponseBodyConverter();
    
        @Override public Void convert(ResponseBody value) throws IOException {
          value.close();
          return null;
        }
      }
    

    从源码我们可以看出当type 是Void类型时,BuiltInConverters将ResponseBody 资源关闭,并转换为Void类型

    当既不是ResponseBody也不是Void,返回null;
    然后我们来看看BuiltInConverters的requestBodyConverter

    
    @Override
      public Converter<?, RequestBody> requestBodyConverter(Type type,
          Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
        if (RequestBody.class.isAssignableFrom(Utils.getRawType(type))) {
          return RequestBodyConverter.INSTANCE;
        }
        return null;
      }
    
    static final class RequestBodyConverter implements Converter<RequestBody, RequestBody> {
        static final RequestBodyConverter INSTANCE = new RequestBodyConverter();
    
        @Override public RequestBody convert(RequestBody value) throws IOException {
          return value;
        }
    
    
    

    从代码可以看出,如果type类型是RequestBody,直接返回RequestBodyConverter,而RequestBodyConverter的convert没做任何操作,如果type类型是其他,则返回null;

    由上面分析可以得出一个结论,BuiltInConverters只处理RequestBody,和ResponseBody,其他类型一律null;

    然后我们看看
    new Retrofit.Builder()
    .baseUrl("https://api.github.com/")
    .build();
    的build

    public Retrofit build() {
          if (baseUrl == null) {
            throw new IllegalStateException("Base URL required.");
          }
    
          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> adapterFactories = new ArrayList<>(this.adapterFactories);
          adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
    
          // Make a defensive copy of the converters.
          List<Converter.Factory> converterFactories = new ArrayList<>(this.converterFactories);
    
          return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,
              callbackExecutor, validateEagerly);
        }
    

    build的第一行代码

    if (baseUrl == null) {
            throw new IllegalStateException("Base URL required.");
          }
    

    如果baseUrl为空,会抛一个IllegalStateException异常,这也是为什么在Builder类注释里面,

    • Calling {@link #baseUrl} is required before calling {@link #build()}.

    要求必须设置baseUrl的原因

    然后我们再看看

     okhttp3.Call.Factory callFactory = this.callFactory;
          if (callFactory == null) {
            callFactory = new OkHttpClient();
          }
    

    当callFactory为空时,会设置一个默认OkHttpClient用于创建call,实现http请求

    Executor callbackExecutor = this.callbackExecutor;
          if (callbackExecutor == null) {
            callbackExecutor = platform.defaultCallbackExecutor();
          }
    

    当没有设置callbackExecutor时,会从platform获取一个默认的Executor。。
    O__O "…platform是什么?

    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;
      }
    
      @Nullable Object invokeDefaultMethod(Method method, Class<?> declaringClass, Object object,
          @Nullable Object... args) throws Throwable {
        throw new UnsupportedOperationException();
      }
    
      @IgnoreJRERequirement // Only classloaded and used on Java 8.
      static class Java8 extends Platform {
        @Override boolean isDefaultMethod(Method method) {
          return method.isDefault();
        }
    
        @Override Object invokeDefaultMethod(Method method, Class<?> declaringClass, Object object,
            @Nullable Object... args) throws Throwable {
          // Because the service interface might not be public, we need to use a MethodHandle lookup
          // that ignores the visibility of the declaringClass.
          Constructor<Lookup> constructor = Lookup.class.getDeclaredConstructor(Class.class, int.class);
          constructor.setAccessible(true);
          return constructor.newInstance(declaringClass, -1 /* trusted */)
              .unreflectSpecial(method, declaringClass)
              .bindTo(object)
              .invokeWithArguments(args);
        }
      }
    
      static class Android extends Platform {
        @Override public Executor defaultCallbackExecutor() {
          return new MainThreadExecutor();
        }
    
        @Override CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
          if (callbackExecutor == null) throw new AssertionError();
          return new ExecutorCallAdapterFactory(callbackExecutor);
        }
    
        static class MainThreadExecutor implements Executor {
          private final Handler handler = new Handler(Looper.getMainLooper());
    
          @Override public void execute(Runnable r) {
            handler.post(r);
          }
        }
      }
    }
    
    
      Builder(Platform platform) {
          this.platform = platform;
          // 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());
        }
    
        public Builder() {
          this(Platform.get());
        }
    
    

    当我们new Buidler时会get一个Android Platform,
    我们来看看

    static class Android extends Platform {
        @Override public Executor defaultCallbackExecutor() {
          return new MainThreadExecutor();
        }
    
        @Override CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
          if (callbackExecutor == null) throw new AssertionError();
          return new ExecutorCallAdapterFactory(callbackExecutor);
        }
    
        static class MainThreadExecutor implements Executor {
          private final Handler handler = new Handler(Looper.getMainLooper());
    
          @Override public void execute(Runnable r) {
            handler.post(r);
          }
        }
      }
    

    所以当没有设置callbackExecutor时,会从platform获取一个默认的Executor。。而这个默认Executor是在main线程下的

    我们继续看build()源码

    // Make a defensive copy of the adapters and add the default Call adapter.
          List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);
          adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
    
    

    adapterFactories添加了一个
    platform.defaultCallAdapterFactory,我们知道这时候的platform是Android,而这个defaultCallAdapterFactory是ExecutorCallAdapterFactory
    那么让我们看看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;
          }
    
          @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");
    
          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();
        }
      }
    }
    

    我们从get方法看起,
    当return的类型不是call类型,直接return,

    static Type getCallResponseType(Type returnType) {
        if (!(returnType instanceof ParameterizedType)) {
          throw new IllegalArgumentException(
              "Call return type must be parameterized as Call<Foo> or Call<? extends Foo>");
        }
        return getParameterUpperBound(0, (ParameterizedType) returnType);
      }
    

    而从getCallResponseType可以看出,如果Call不是泛型会抛出一个IllegalArgumentException,换句话说,ExecutorCallAdapterFactory只处理泛型Call,

    new CallAdapter<Object, Call<?>>() {
          @Override public Type responseType() {
            return responseType;
          }
    
          @Override public Call<Object> adapt(Call<Object> call) {
            return new ExecutorCallbackCall<>(callbackExecutor, call);
          }
    

    responseType () return了Call的泛型类型
    adapt() return 一个ExecutorCallbackCall
    那么我们来看看这个ExecutorCallbackCall实现了什么
    ExecutorCallbackCall是ExceutorCallAdapterFactory的内部类

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

    ExecutorCallbackCall实现了Call接口而实际处理请求的是delegate,没错这是个委托模式(或者叫静态代理模式)而这个call是有一个默认(或者你自己设置的)okhttpClient生成的;

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

    我们知道,之前传进ExceutorCallAdapterFactory的Executor是在main线程下的,所以。。这里也没什么好讲了,都是回调到主线程里执行

    好啦,从这里我们就把整个Retrofit初始化的全给讲完了,

    相关文章

      网友评论

          本文标题:retrofit源码解析(一)

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