专栏名称: 俞其荣
向前跑 迎着冷眼和嘲笑 与 http://yuqirong.me 保持同步更新
目录
相关文章推荐
中产先生  ·  中央发布重磅文件:居民的日子就要好过了? ·  13 小时前  
单向街书店  ·  字面意思在哪里 | 友好门店地图 ·  3 天前  
新京报书评周刊  ·  荷花开了:和王维、苏轼一起看荷花丨周末读诗 ·  3 天前  
51好读  ›  专栏  ›  俞其荣

Retrofit源码解析

俞其荣  · 简书  ·  · 2017-08-17 17:14

正文

请到「今天看啥」查看全文


关于上面种种奇怪的类,我们先不关心,因为之后我们遇到了再分析。我们先把目光聚焦在 Retrofit 类上。

Retrofit

Retrofit 类的构造方法没什么好看的,在这就不讲了。

得到 Retrofit 对象后就是调用 create(final Class<T> service) 方法来创建我们 API 接口的实例。

所以我们需要跟进 create(final Class<T> service) 中来看下:

  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, 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);
            }
            if (platform.isDefaultMethod(method)) {
              return platform.invokeDefaultMethod(method, service, proxy, args);
            }
            // 将接口中的方法构造为 ServiceMethod
            ServiceMethod serviceMethod = loadServiceMethod(method);
            OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
            return serviceMethod.callAdapter.adapt(okHttpCall);
          }
        });
  }

在上面的代码中,最关键的就是动态代理。实际上,进行网络操作的都是通过代理类来完成的。如果对动态代理不太懂的同学请自行百度了,这里就不多讲了。

重点就是

// 将接口中的方法构造为 ServiceMethod
ServiceMethod serviceMethod = loadServiceMethod(method);
OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);

这三句代码,下面我们着重来看。

在代理中,会根据参数中传入的具体接口方法来构造出对应的 serviceMethod ServiceMethod 类的作用就是把接口的方法适配为对应的 HTTP call 。

  ServiceMethod loadServiceMethod(Method method) {
    ServiceMethod result;
    synchronized (serviceMethodCache) {
      // 先从缓存中取,若没有就去创建对应的 ServiceMethod
      result = serviceMethodCache.get(method);
      if (result == null) {
        // 没有缓存就创建,之后再放入缓存中
        result = new ServiceMethod.Builder(this, method).build();
        serviceMethodCache.put(method, result);
      }
    }
    return result;
  }

可以看到在内部还维护了一个 serviceMethodCache 来缓存 ServiceMethod ,以便提高效率。我们就直接来看 ServiceMethod 是如何被创建的吧。

ServiceMethod.Builder

发现 ServiceMethod 也是通过建造者模式来创建对象的。那就进入对应构造方法:







请到「今天看啥」查看全文