美文网首页android
retrofit源码解析--异步请求

retrofit源码解析--异步请求

作者: 二妹是只猫 | 来源:发表于2019-03-19 15:07 被阅读29次
    Retrofit.png

    retrofit请求具体实现类为OkHttpCall,所以本篇直接来到OkHttpCall分析它的异步请求

    final class OkHttpCall<T> implements Call<T> {
      private final ServiceMethod<T, ?> serviceMethod;
      private final @Nullable Object[] args;
    
      private volatile boolean canceled;
    
      @GuardedBy("this")
    1 private @Nullable okhttp3.Call rawCall;
      @GuardedBy("this")
      private @Nullable Throwable creationFailure; // Either a RuntimeException or IOException.
      @GuardedBy("this")
      private boolean executed;
    
      @Override public void enqueue(final Callback<T> callback) {
        checkNotNull(callback, "callback == null");
    
        okhttp3.Call call;
        Throwable failure;
    
        synchronized (this) {
          if (executed) throw new IllegalStateException("Already executed.");
          executed = true;
    2     call = rawCall = createRawCall();
        }
    
        if (failure != null) {
          callback.onFailure(this, failure);
          return;
        }
    
        if (canceled) {
          call.cancel();
        }
    
    3   call.enqueue(new okhttp3.Callback() {
          @Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse)
              throws IOException {
            Response<T> response;
            try {
    4         response = parseResponse(rawResponse);
            } catch (Throwable e) {
              callFailure(e);
              return;
            }
            callSuccess(response);
          }
        '省略部分代码'
      }
    
    • 1.中看出retrofit实际网络请求使用的是原生的okhttp
    • 2.createRawCall:
    private okhttp3.Call createRawCall() throws IOException {
        Request request = serviceMethod.toRequest(args);
        okhttp3.Call call = serviceMethod.callFactory.newCall(request);
        if (call == null) {
          throw new NullPointerException("Call.Factory returned null.");
        }
        return call;
    }
    

    从serviceMethod获取到请求参数并封装成request对象返回,ServiceMethod主要就是将retrofit网络请求的各种参数进行封装,是retrofit的核心部件
    将获取到的request传入okhttp的RealCall获取到原生RealCall对象

    • 3.调用RealCall的异步方法enqueue
    • 4.将获取到的返回进行解析parseResponse,在返回到retrofit的callback:
    Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
      ResponseBody rawBody = rawResponse.body();
    
      // Remove the body's source (the only stateful object) so we can pass the response along.
      rawResponse = rawResponse.newBuilder()
          .body(new NoContentResponseBody(rawBody.contentType(), rawBody.contentLength()))
          .build();
    
      int code = rawResponse.code();
      if (code < 200 || code >= 300) {
        try {
          // Buffer the entire body to avoid future I/O.
          ResponseBody bufferedBody = Utils.buffer(rawBody);
          return Response.error(bufferedBody, rawResponse);
        } finally {
          rawBody.close();
        }
      }
    
      if (code == 204 || code == 205) {
        rawBody.close();
        return Response.success(null, rawResponse);
      }
    
      ExceptionCatchingRequestBody catchingBody = new ExceptionCatchingRequestBody(rawBody);
      try {
        T body = serviceMethod.toResponse(catchingBody);
        return Response.success(body, rawResponse);
      } catch (RuntimeException e) {
        // If the underlying source threw an exception, propagate that rather than indicating it was
        // a runtime exception.
        catchingBody.throwIfCaught();
        throw e;
      }
    }
    

    相关文章

      网友评论

        本文标题:retrofit源码解析--异步请求

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