美文网首页
Retrofit(六)--ServiceMethod

Retrofit(六)--ServiceMethod

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

移步Retrofit--网络通讯框架

ServiceMethod的工作

  • 解析Method,即解析请求方法的注解参数等内容
  • 生成真正的网络请求OkHttp#Call对象
  • 通过Converter.Factory解析网络请求返回的数据
  • 通过ServiceMethod本身生成OkHttpCall
  • 通过ExecutorCallAdapterFactory获取CallAdapter,进而通过CallAdapter和OkHttpCall可获取ExecutorCallbackCall,即是最终暴露给使用者的Call

源码分析

1. 初始化的入口

  Retrofit#loadServiceMethod
  ServiceMethod<?, ?> loadServiceMethod(Method method) {
    ServiceMethod<?, ?> result = serviceMethodCache.get(method);
    if (result != null) return result;

    synchronized (serviceMethodCache) {
      result = serviceMethodCache.get(method);
      if (result == null) {
        //这里即为入口
        result = new ServiceMethod.Builder<>(this, method).build();
        serviceMethodCache.put(method, result);
      }
    }
    return result;
  }

2. ServiceMethod. Builder()

    Builder(Retrofit retrofit, Method method) {
      //retrofit实例
      this.retrofit = retrofit;
      //网络请求方法
      this.method = method;
      //网络请求方法的注解
      this.methodAnnotations = method.getAnnotations();
      //获取网络请求方法里的注解的类型
      this.parameterTypes = method.getGenericParameterTypes();
      //获取网络请求方法里的注解的内容
      this.parameterAnnotationsArray = method.getParameterAnnotations();
    }

3. ServiceMethod. Builder#build()

    public ServiceMethod build() {
      //步骤 1
      callAdapter = createCallAdapter();
      ...
      //步骤 2,和步骤 1类似,获取请求数据解析器
      responseConverter = createResponseConverter();
      //解析请求接口中的所有注释
      for (Annotation annotation : methodAnnotations) {
        parseMethodAnnotation(annotation);
      }
      ...
      //主要是解析网络请求接口的参数,包括自定义请求接口参数和配置的请求参数
      int parameterCount = parameterAnnotationsArray.length;
      parameterHandlers = new ParameterHandler<?>[parameterCount];
      for (int p = 0; p < parameterCount; p++) {
        Type parameterType = parameterTypes[p];
        if (Utils.hasUnresolvableType(parameterType)) {
          throw parameterError(p, "Parameter type must not include a type variable or wildcard: %s",
              parameterType);
        }

        Annotation[] parameterAnnotations = parameterAnnotationsArray[p];
        if (parameterAnnotations == null) {
          throw parameterError(p, "No Retrofit annotation found.");
        }

        parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);
      }
      ...
      //实例化并返回对象ServiceMethod
      return new ServiceMethod<>(this);
    }

主要操作都在注释内解释,接下来看步骤 1 的方法操作

3.1. ServiceMethod. Builder#createCallAdapter()
    private CallAdapter<T, R> createCallAdapter() {
      Type returnType = method.getGenericReturnType();
      ...
      try {
        //通过retrofit获取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内持有的callAdapterFactories获取到可以获取用户做网络请求的Call对象ExecutorCallbackCall的对象CallAdapter

4. ServiceMethod#adapt()

  T adapt(Call<R> call) {
    return callAdapter.adapt(call);
  }

生成ExecutorCallbackCall,并返回给用户

5. ServiceMethod#toCall()

  okhttp3.Call toCall(@Nullable Object... args) throws IOException {
    RequestBuilder requestBuilder = new RequestBuilder(httpMethod, baseUrl, relativeUrl, headers,
        contentType, hasBody, isFormEncoded, isMultipart);
    ...
    return callFactory.newCall(requestBuilder.build());
  }

根据method请求和args参数生成真正的网络请求对象OkHttp#Call

6. ServiceMethod#toResponse()

  R toResponse(ResponseBody body) throws IOException {
    return responseConverter.convert(body);
  }

解析数据为用户想要的类型

相关文章

网友评论

      本文标题:Retrofit(六)--ServiceMethod

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