androidsj的专栏

程序员的圈圈里

Retrofit - 13 retrofit中serviceMethod对象解析
ServiceMethod serviceMethod = Retrofit.this.loadServiceMethod(method);
OkHttpCall okHttpCall = new OkHttpCall(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);

loadServiceMethod其实就是加载ServiceMethod,它是对应我们接口中定义好的一个网络请求方法,例如getCall这个方法,最后还是交给OKHTTP,

ServiceMethod<?, ?> loadServiceMethod(Method method) {
    ServiceMethod<?, ?> result = serviceMethodCache.get(method);
    if (result != null) return result;
    // 设置了一个线程同步锁,主要是为了保证我们的线程的数据安全。
    synchronized (serviceMethodCache) {
      /**
       * 获取到我们的ServiceMethod,这个ServiceMethod采用的是单例模式进行创建的,
       * 它其实有一个serciveMethodCache缓存池进行获取。
       */
      result = serviceMethodCache.get(method);
      /**
       * 非空判断。如果没有缓存就自己创建一个ServiceMethod对象,
       * 它是通过构建者模式Builder来进行创建的。
       */
      if (result == null) {
        // 最终调用build()来创建我们实际的ServiceMethod对象的创建。
        result = new ServiceMethod.Builder<>(this, method).build();
        /**
         * 放到缓存池当中,以HTTP请求方法做为KEY,
         * ServiceMethod这个对象做为VALUES,保存在这个缓存池当中。
         */
        serviceMethodCache.put(method, result);
      }
    }
    return result;
  }

final class ServiceMethod<R, T> {
  // Upper and lower characters, digits, underscores, and hyphens, starting with a character.
  static final String PARAM = "[a-zA-Z][a-zA-Z0-9_-]*";
  static final Pattern PARAM_URL_REGEX = Pattern.compile("\\{(" + PARAM + ")\\}");
  static final Pattern PARAM_NAME_REGEX = Pattern.compile(PARAM);
  /**
   * 网络请求工厂,用于生产我们的网络请求,
   * 这个call在Retrofit当中其实就是我们的OKHTTP Call,
   * 而OKHTTP Call呢就是Retrofit对它做了封装。它内部其实是调用了OKHTTP Call。
   */
  private final okhttp3.Call.Factory callFactory;
  // 网络请求适配器,把我们的Call请求适用于不同的平台。例如:RxJava等。
  private final CallAdapter<R, T> callAdapter;

  private final HttpUrl baseUrl;
  // 数据转换器。作用就是把服务器返回给我们的数据,转换成我们需要的java Bean对象。
  private final Converter<ResponseBody, R> responseConverter;
  // 网络请求的HTTP方法,比如:get, post, put等等。
  private final String httpMethod;
  // 网络请求的相对地址。 相对地址 + baseUrl = 网络请求的绝对地址。
  private final String relativeUrl;
  // HTTP网络请求的请求头。键值对。
  private final Headers headers;
  // HTTP网络请求报文的body类型。
  private final MediaType contentType;
  private final boolean hasBody;
  private final boolean isFormEncoded;
  private final boolean isMultipart;
  // 方法参数处理器,
  private final ParameterHandler<?>[] parameterHandlers;
ServiceMethod这个对象,其实完全包含了我们访问网络的所以基本信息,它都涵括在内了,以下是它的构造函数。
ServiceMethod(Builder<R, T> builder) {
    this.callFactory = builder.retrofit.callFactory();
    this.callAdapter = builder.callAdapter;
    this.baseUrl = builder.retrofit.baseUrl();
    this.responseConverter = builder.responseConverter;
    this.httpMethod = builder.httpMethod;
    this.relativeUrl = builder.relativeUrl;
    this.headers = builder.headers;
    this.contentType = builder.contentType;
    this.hasBody = builder.hasBody;
    this.isFormEncoded = builder.isFormEncoded;
    this.isMultipart = builder.isMultipart;
    this.parameterHandlers = builder.parameterHandlers;
  }

接下来我们来看下 ServiceMethod 的内部类 Builder

Builder(Retrofit retrofit, Method method) {
      this.retrofit = retrofit;
      // 获取网络请求方法(get,post等)
      this.method = method;
      // 获取网络请求接口方法里面的注解
      this.methodAnnotations = method.getAnnotations();
      // 获取网络请求接口方法里的参数的类型,它是一个types。
      this.parameterTypes = method.getGenericParameterTypes();
      // 获取网络请求接口方法里注解的完整内容
      this.parameterAnnotationsArray = method.getParameterAnnotations();
    }

接下来,我们来看下上面的这行代码:result = new ServiceMethod.Builder<>(this, method).build();

最终调用build()来创建我们实际的ServiceMethod对象的创建。


private CallAdapter<T, R> createCallAdapter() {
      //获取网络请求接口方法里的返回的类型。
      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.");
      }
      //获取网络请求接口里的注解,调用的反射当中的getAnnotations()。
      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 - 13 retrofit中serviceMethod对象解析

最多只允许输入30个字

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭