美文网首页
Retrofit(三)--Retrofit

Retrofit(三)--Retrofit

作者: azu_test | 来源:发表于2019-03-01 14:51 被阅读0次

    移步Retrofit--网络通讯框架

    Retrofit的工作

    • 设置url的前半部分
    • 生产平台适配器Platform
    • 通过Platform生成MainThreadExecutorExecutorCallAdapterFactory
    • 通过外部添加数据转换器Converter.Factory
    • 通过create()方法生成网络请求接口的代理

    源码分析

    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请求对象

    相关文章

      网友评论

          本文标题:Retrofit(三)--Retrofit

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