Retrofit2源码学习之流程详解

综述

Retrofit到一个实际请求/响应的过程包括

  • 创建ServiceMethod,调用ServiceMethod.build()
  • 调用OkHttpCall(ServiceMethod,args)创建OkHttpCall对象,
  • 调用 CallAdapter.adapt(okHttpCall)创建关联执行器Executor和Call的应用层Call类,Android默认为ExecutorCallbackCall

源码研究

  • 创建ServiceMethod

ServiceMethod.build()

  public ServiceMethod build() {
      //通过Retrofit.nextCallAdapter获取callAdapter,有自定义就用自定义,没有就用默认ExecutorCallAdapterFactory
      callAdapter = createCallAdapter();
      responseType = callAdapter.responseType();
      //返回类型验证
      if (responseType == Response.class || responseType == okhttp3.Response.class) {
        throw methodError("'"
            + Utils.getRawType(responseType).getName()
            + "' is not a valid response body type. Did you mean ResponseBody?");
      }
      //通过Retrofit.nextResponseBodyConverter处理转换异常,获得自定义转换器
      responseConverter = createResponseConverter();
      //解析自定义的注解成URL组件
      for (Annotation annotation : methodAnnotations) {
        parseMethodAnnotation(annotation);
      }

      //错误处理
      ...
      //构建参数替换的辅助数组parameterHandlers
      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);
      }
      //错误处理
     ...
      return new ServiceMethod<>(this);
    }
  • 用户调用enqueue方法发起异步请求

ExecutorCallbackCall.enqueue()

    @Override public void enqueue(final Callback<T> callback) {
      checkNotNull(callback, "callback == null");
      //调用OkhttpCall的enqueue方法,Executor执行响应结果
      delegate.enqueue(new Callback<T>() {
        
        }
      });
    }

OkHttpCall. enqueue

 @Override public void enqueue(final Callback<T> callback) {
    checkNotNull(callback, "callback == null");

    okhttp3.Call call;
    Throwable failure;

    synchronized (this) {
          ...
          //这里创建请求报文获得realCall
          call = rawCall = createRawCall();
           ...
    }
    //realCall发起异步请求
    call.enqueue(new okhttp3.Callback() {
           ...
          //转换响应报文
          response = parseResponse(rawResponse);
          ...
   
    });
  }

createRawCall

  private okhttp3.Call createRawCall() throws IOException {
    //创建request报文
    Request request = serviceMethod.toRequest(args);
    //获得okhttp.realCall
    okhttp3.Call call = serviceMethod.callFactory.newCall(request);
    if (call == null) {
      throw new NullPointerException("Call.Factory returned null.");
    }
    return call;
  }

serviceMethod.toRequest(args)

  Request toRequest(@Nullable Object... args) throws IOException {
    RequestBuilder requestBuilder = new RequestBuilder(httpMethod, baseUrl, relativeUrl, headers,
        contentType, hasBody, isFormEncoded, isMultipart);
    ...
    @SuppressWarnings("unchecked") // It is an error to invoke a method with the wrong arg types.
    ParameterHandler<Object>[] handlers = (ParameterHandler<Object>[]) parameterHandlers;
    //根据先前的parameterHandlers进行参数转换
    for (int p = 0; p < argumentCount; p++) {
      handlers[p].apply(requestBuilder, args[p]);
    }
    //创建request报文
    return requestBuilder.build();
  }

parseResponse

 Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
    ResponseBody rawBody = rawResponse.body();
    //异常处理,200-299成功状态码,204和205没有响应body
   ...
      //serviceMethod.toResponse用户转换器转换
      T body = serviceMethod.toResponse(catchingBody);
      return Response.success(body, rawResponse);

  }

总结

通过梳理大体了解的Retrofit的整体结构和流程,当然还有很多的细节没有讨论,需要时可以查看相应的源码。
Retrofit源码本身并不复杂,但是Retrofit的架构设计,解耦所透露的架构经验,思想,规范等是非常值得我们学习和参照设计的。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 适配器模式上一篇文章我们已经分析了Retrofit解析注解封装进ServiceMethod的流程,读者在这里要记住...
    andcoder阅读 769评论 0 2
  • 最近非常流行 Retrofit+RxJava+OkHttp 这一整套的网络请求和异步操作的开源框架,从 Jake ...
    慌不要慌阅读 2,014评论 1 7
  • Retrofit这个开源库出来也有一定年头了,记得之前还是在V1.0的版本的时候,之前在三月份也写过一个Retro...
    lovejjfg阅读 1,504评论 0 5
  • 一、什么是Retrofit A type-safe HTTP client for Android and Jav...
    andcoder阅读 837评论 2 3
  • 好的开场白是成功的一半,很多演讲高手都说,如果没有一个好的开头,想在整个演说过程中做到轻松、巧妙地与听众交流思想交...
    苗轩鸣阅读 558评论 0 2

友情链接更多精彩内容