Retrofit(三)--Retrofit

2019-03-01  本文已影响0人  azu_test

移步Retrofit--网络通讯框架

Retrofit的工作

源码分析

1. Retrofit成员变量分析

public final class Retrofit {
  private final Map<Method, ServiceMethod<?, ?>> serviceMethodCache = new ConcurrentHashMap<>();
  //网络请求工厂,默认为OkHttpClient
  final okhttp3.Call.Factory callFactory;
  //请求url前半部,基地址
  final HttpUrl baseUrl;
  //数据转换器工厂集
  final List<Converter.Factory> converterFactories;
  //网络请求适配器工厂集
  final List<CallAdapter.Factory> callAdapterFactories;
  //请求结果线程切换执行器,默认是回到UI线程内
  final @Nullable Executor callbackExecutor;
  //标志位、是否马上解析接口方法
  final boolean validateEagerly;
  ...
}

上面的这些成员变量最终都会通过建造者模式Retrofit.build()方法内的new Retrofit(...)赋值

2. 内部类Builder源码分析

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

Platform会单独分析,这里只知道Platform可以生成MainThreadExecutorExecutorCallAdapterFactory

  1. MainThreadExecutor是回调到Ui线程的执行器
  2. ExecutorCallAdapterFactory是网络请求适配器,可以生成最后交付给用户使用的Call对象。ExecutorCallAdapterFactory也会单独分析。

3. Build.build()源码分析

    public Retrofit build() {
      if (baseUrl == null) {
        throw new IllegalStateException("Base URL required.");
      }
      //默认为空,初始化为OkHttpClient
      okhttp3.Call.Factory callFactory = this.callFactory;
      if (callFactory == null) {
        callFactory = new OkHttpClient();
      }
      //获取回调执行器,如果没有则通过Platform创建一个主线程回调执行器
      Executor callbackExecutor = this.callbackExecutor;
      if (callbackExecutor == null) {
        callbackExecutor = platform.defaultCallbackExecutor();
      }

      //设置CallAdapter.Factory列表
      //我们可以通过addCallAdapterFactory()方法加入我们自己的adapter,例如rxjava2的callAdapter,
      //系统会在其后加入一个默认的Adapter,一旦用户没有指定适配器就使用默认的,Android使用ExecutorCallAdapterFactory
      List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
      callAdapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));

      //设置Converter.Factory列表
      //与上面不同的是,这次首先加入一个默认的,然后才加入用户设定的,上面是先添加用户的,然后添加默认的。
      List<Converter.Factory> converterFactories =
          new ArrayList<>(1 + this.converterFactories.size());
      converterFactories.add(new BuiltInConverters());
      converterFactories.addAll(this.converterFactories);

      //实例化Retrofit
      return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
          unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
    }

4. Retrofit#loadServiceMethod(),获取网络请求接口的ServiceMethod

  //存取ServiceMethod
  private final Map<Method, ServiceMethod<?, ?>> serviceMethodCache = 
          new ConcurrentHashMap<>();

  ServiceMethod<?, ?> loadServiceMethod(Method method) {
    //从缓存中取ServiceMethod
    ServiceMethod<?, ?> result = serviceMethodCache.get(method);
    if (result != null) return result;

    synchronized (serviceMethodCache) {
      result = serviceMethodCache.get(method);
      if (result == null) {
        //如果缓存中没有则重新创建一个ServiceMethod
        result = new ServiceMethod.Builder<>(this, method).build();
        //加入缓存中
        serviceMethodCache.put(method, result);
      }
    }
    return result;
  }

ConcurrentHashMap是HashMap的一个线程安全的、支持高效并发的版本
通过retrofit和method(网络请求接口方法)创建网络请求接口方法解析对象,具体的操作会在ServiceMethod中详细分析

5. 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() {
          private final Platform platform = Platform.get();

          @Override public Object invoke(Object proxy, Method method, @Nullable Object[] args)
              throws Throwable {
            if (method.getDeclaringClass() == Object.class) {
              return method.invoke(this, args);
            }
            if (platform.isDefaultMethod(method)) {
              return platform.invokeDefaultMethod(method, service, proxy, args);
            }
            //方法 1
            ServiceMethod<Object, Object> serviceMethod =
                (ServiceMethod<Object, Object>) loadServiceMethod(method);
            //方法 2
            OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
            //方法 3
            return serviceMethod.adapt(okHttpCall);
          }
        });
  }

接口调用方法进行网络请求时实际上会进入代理对象的invoke回调方法内,主要的操作也是如注释中的方法1 2 3

  • 方法1 获取接口方法对应的方法解析对象ServiceMethod
  • 方法2 是通过Service和方法参数生成新的OkHttpCall(真正做网络操作的地方),OkHttpCall会单独分析
  • 方法3 是通过ServiceMethod获取最终交付给用户的Call请求对象
上一篇下一篇

猜你喜欢

热点阅读