网络请求工具retrofit2.9.0源码分析

717 阅读4分钟

常用retrofit请求网络方法

image.png

retrofit创建源码分析

image.png

Builder()构建后里面为Platform.get()方法

image.png

Platform.get()方法返回PLATFORM为findPlatform方法,如果jvm name为Dalvik怎么为Android平台,否则为自身


  static final Platform PLATFORM = findPlatform();

  static Platform get() {
    return PLATFORM;
  }

  private static Platform findPlatform() {
    return "Dalvik".equals(System.getProperty("java.vm.name"))
        ? new Android() //
        : new Platform(true);
  }
  
  
  
  
  static final class Android extends Platform {
    
    Android() {
      super(Build.VERSION.SDK_INT >= 24);
    }

    @Override
    public Executor defaultCallbackExecutor() {
      return new MainThreadExecutor();
    }

    @Nullable
    @Override
    Object invokeDefaultMethod(
        Method method, Class<?> declaringClass, Object object, Object... args) throws Throwable {
      if (Build.VERSION.SDK_INT < 26) {
        throw new UnsupportedOperationException(
            "Calling default methods on API 24 and 25 is not supported");
      }
      return super.invokeDefaultMethod(method, declaringClass, object, args);
    }

    static final class MainThreadExecutor implements Executor {
      private final Handler handler = new Handler(Looper.getMainLooper());

      @Override
      public void execute(Runnable r) {
        handler.post(r);
      }
    }
  }

所以android平台defaultCallbackExecutor为MainThreadExecutor,把runnable线程通过handler 、post到主线程....之后的各个具体设置,感兴趣的可以自己去仔细看

retrofit调用流程分析

retrofit.create(service).method()

通过Retrofti对象创建请求接口,把我们自定义的请求接口类,放到Proxy重新生成一个一个代理类,每次调用类里的方法时,通过代理会走invoke方法,然后判断是否为默认方法,若不是默认方发则使用loadServiceMethod.invoke调用

 public <T> T create(final Class<T> service) {
    validateServiceInterface(service);
    return (T)
        //代理模式
        //通过Proxy.newProxyInstance方法里的拿到classLoader、service类,在Proxy中克隆一个新的class
        Proxy.newProxyInstance(
            service.getClassLoader(),
            new Class<?>[] {service},
            new InvocationHandler() {
              private final Platform platform = Platform.get();
              private final Object[] emptyArgs = new Object[0];

              @Override
              public @Nullable Object invoke(Object proxy, Method method, @Nullable 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);
                }
                args = args != null ? args : emptyArgs;
         
                return platform.isDefaultMethod(method)
                    ? platform.invokeDefaultMethod(method, service, proxy, args)
                    : loadServiceMethod(method).invoke(args);
              }
            });
  }
  
  
 private void validateServiceInterface(Class<?> service) {
     //判断参数的class是否为interface接口
    if (!service.isInterface()) {
      throw new IllegalArgumentException("API declarations must be interfaces.");
    }
    Deque<Class<?>> check = new ArrayDeque<>(1);
    check.add(service);
    while (!check.isEmpty()) {
      Class<?> candidate = check.removeFirst();
      if (candidate.getTypeParameters().length != 0) {
        StringBuilder message =
            new StringBuilder("Type parameters are unsupported on ").append(candidate.getName());
        if (candidate != service) {
          message.append(" which is an interface of ").append(service.getName());
        }
        throw new IllegalArgumentException(message.toString());
      }
      Collections.addAll(check, candidate.getInterfaces());
    }

    //设置validateEagerly为true时检查
    if (validateEagerly) {
      Platform platform = Platform.get();
      for (Method method : service.getDeclaredMethods()) {
        //当方法不是默认方发和静态方法,则调用loadServiceMethod  
        if (!platform.isDefaultMethod(method) && !Modifier.isStatic(method.getModifiers())) {
          loadServiceMethod(method);
        }
      }
    }
  }

  ServiceMethod<?> loadServiceMethod(Method method) {
    //serviceMethodCache会首先在map中查找是否有此方法
    ServiceMethod<?> result = serviceMethodCache.get(method);
    if (result != null) return result;
    
    synchronized (serviceMethodCache) {
      result = serviceMethodCache.get(method);
   
      if (result == null) {
        result = ServiceMethod.parseAnnotations(this, method);
        //如果没有取到则把此方法放到serviceMethodCache中
        serviceMethodCache.put(method, result);
      }
    }
    return result;
  }

result = ServiceMethod.parseAnnotations(this, method);这个方法中会在通过RequstFactory.parseAnnotation方法获取RequestFactory对象,最后把requestFactory对象传到HttpServiceMethod的parseAnnotations方法中

abstract class ServiceMethod<T> {
  static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
    RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);

    Type returnType = method.getGenericReturnType();
    if (Utils.hasUnresolvableType(returnType)) {
      throw methodError(
          method,
          "Method return type must not include a type variable or wildcard: %s",
          returnType);
    }
    if (returnType == void.class) {
      throw methodError(method, "Service methods cannot return void.");
    }
    
    return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
  }

  abstract @Nullable T invoke(Object[] args);
}
final class RequestFactory {

  static RequestFactory parseAnnotations(Retrofit retrofit, Method method) {
    return new Builder(retrofit, method).build();
  }

然后使用RequestFactory中的Builder去build方法构建

 static final class Builder {
  
      Builder(Retrofit retrofit, Method method) {
          this.retrofit = retrofit;
          this.method = method;
          this.methodAnnotations = method.getAnnotations();
          this.parameterTypes = method.getGenericParameterTypes();
          this.parameterAnnotationsArray = method.getParameterAnnotations();
     }
  
      RequestFactory build() {
          for (Annotation annotation : methodAnnotations) {
            parseMethodAnnotation(annotation);
          }

          if (httpMethod == null) {
            throw methodError(method, "HTTP method annotation is required (e.g., @GET, @POST, etc.).");
          }

          if (!hasBody) {
            if (isMultipart) {
              throw methodError(
                  method,
                  "Multipart can only be specified on HTTP methods with request body (e.g., @POST).");
            }
            if (isFormEncoded) {
              throw methodError(
                  method,
                  "FormUrlEncoded can only be specified on HTTP methods with "
                      + "request body (e.g., @POST).");
            }
          }

          int parameterCount = parameterAnnotationsArray.length;
          parameterHandlers = new ParameterHandler<?>[parameterCount];
          for (int p = 0, lastParameter = parameterCount - 1; p < parameterCount; p++) {
            parameterHandlers[p] =
                parseParameter(p, parameterTypes[p], parameterAnnotationsArray[p], p == lastParameter);
          }

          if (relativeUrl == null && !gotUrl) {
            throw methodError(method, "Missing either @%s URL or @Url parameter.", httpMethod);
          }
          if (!isFormEncoded && !isMultipart && !hasBody && gotBody) {
            throw methodError(method, "Non-body HTTP method cannot contain @Body.");
          }
          if (isFormEncoded && !gotField) {
            throw methodError(method, "Form-encoded method must contain at least one @Field.");
          }
          if (isMultipart && !gotPart) {
            throw methodError(method, "Multipart method must contain at least one @Part.");
          }

          return new RequestFactory(this);
        }
  }

在build方法里 可以看到methodAnnotations通过传递过来的method方法获取注解方法,去遍历通过parseMethodAnnotation把请求方法加到路径中,之后往下看到在for循环中最后一次,当为最后一个参数去判断是否为kotlin协程。通过获取rawType为Continuation类,则isKotlinSuspendFunction参数设置为true,最后创建RequestFactory,把build里的参数赋值到RequestFactory的形参中

   if (Utils.getRawType(parameterType) == Continuation.class) {
       isKotlinSuspendFunction = true;
       return null;
   }
   

HttpServiceMethod.parseAnnotations方法则去判断是否为kotlin协程方法,返回不同的adapterType,去创建CallAdapter、之后根据callAdapter得到responseType,在根据responseType获取Converter,然后根据参数去监听各个方法。返回对象invoke()

image.png

以返回对象为CallAdapter为例,invoke后创建OkHttpCall对象然后调用calladapt.adapt方法,往上翻找时发现Calladapter为retrofit中的calladapter,在没有配置时为deafultCallAdapter

image.png 调用adapt方法初始ExecutorCallbackCall对象

retrofit.create(service).method().enqueue()

然后调用enqueue方法,是ExecutorCallbackCall调用enqueue()方法

static final class ExecutorCallbackCall<T> implements Call<T> {
    final Executor callbackExecutor;
    //为上文中传过来的OkHttpCall
    final Call<T> delegate;

    ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) {
      this.callbackExecutor = callbackExecutor;
      this.delegate = delegate;
    }

    @Override
    public void enqueue(final Callback<T> callback) {
      Objects.requireNonNull(callback, "callback == null");
        
      //OkHttpCall调用enqueue方法
      delegate.enqueue(
          new Callback<T>() {
            @Override
            public void onResponse(Call<T> call, final Response<T> response) {
              callbackExecutor.execute(
                  () -> {
                    if (delegate.isCanceled()) {
                      // Emulate OkHttp's behavior of throwing/delivering an IOException on
                      // cancellation.
                      callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled"));
                    } else {
                      callback.onResponse(ExecutorCallbackCall.this, response);
                    }
                  });
            }

            @Override
            public void onFailure(Call<T> call, final Throwable t) {
              callbackExecutor.execute(() -> callback.onFailure(ExecutorCallbackCall.this, t));
            }
          });
    }

final class OkHttpCall<T> implements Call<T> {
    
    .....
    .....
    
      @Override
      public void enqueue(final Callback<T> callback) {
        Objects.requireNonNull(callback, "callback == null");
        //通过OKHttpCall方法调用enqueue
        okhttp3.Call call;
        Throwable failure;

        synchronized (this) {
          if (executed) throw new IllegalStateException("Already executed.");
          executed = true;

          call = rawCall;
          failure = creationFailure;
          if (call == null && failure == null) {
            try {
              //然后创建一个真正的call方法 得到 RealCall对象
              call = rawCall = createRawCall();
            } catch (Throwable t) {
              throwIfFatal(t);
              failure = creationFailure = t;
            }
          }
        }

        if (failure != null) {
          callback.onFailure(this, failure);
          return;
        }

        if (canceled) {
          call.cancel();
        }
       
       //调用realCall的enqueue方法
        call.enqueue(
            new okhttp3.Callback() {
              @Override
              public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
                Response<T> response;
                try {
                  response = parseResponse(rawResponse);
                } catch (Throwable e) {
                  throwIfFatal(e);
                  callFailure(e);
                  return;
                }

                try {
                  callback.onResponse(OkHttpCall.this, response);
                } catch (Throwable t) {
                  throwIfFatal(t);
                  t.printStackTrace(); // TODO this is not great
                }
              }

              @Override
              public void onFailure(okhttp3.Call call, IOException e) {
                callFailure(e);
              }

              private void callFailure(Throwable e) {
                try {
                  callback.onFailure(OkHttpCall.this, e);
                } catch (Throwable t) {
                  throwIfFatal(t);
                  t.printStackTrace(); // TODO this is not great
                }
              }
            });
      }

}

通过上面OkhttpCall对象调用enqueue方法得到realcall对象,并开始调用enqueue方法

image.png

然后在通过OkHttpClient调度器开启一个异步的线程。

image.png 在调度器中把异步线程添加在准备队列中

image.png 然后把准备队列中的线程迭代后加入执行list集合中和放入运行队列中,之后遍历执list,最后通过线程池ThreadPoolExecutor创建executorService执行请求操作。asynCall.executeOn方法

 final class AsyncCall extends NamedRunnable {
    private final Callback responseCallback;
       
    ....
    ....

    /**
     * Attempt to enqueue this async call on {@code executorService}. This will attempt to clean up
     * if the executor has been shut down by reporting the call as failed.
     */
    void executeOn(ExecutorService executorService) {
      assert (!Thread.holdsLock(client.dispatcher()));
      boolean success = false;
      try {
        //执行
        executorService.execute(this);
        success = true;
      } catch (RejectedExecutionException e) {
        InterruptedIOException ioException = new InterruptedIOException("executor rejected");
        ioException.initCause(e);
        transmitter.noMoreExchanges(ioException);
        responseCallback.onFailure(RealCall.this, ioException);
      } finally {
        if (!success) {
          client.dispatcher().finished(this); // This call is no longer running!
        }
      }
    }

    @Override protected void execute() {
      boolean signalledCallback = false;
      //设置请求时长
      transmitter.timeoutEnter();
      try {
        //获取返回的responseBody  
        Response response = getResponseWithInterceptorChain();
        signalledCallback = true;
        responseCallback.onResponse(RealCall.this, response);
      } catch (IOException e) {
        if (signalledCallback) {
          // Do not signal the callback twice!
          Platform.get().log(INFO, "Callback failure for " + toLoggableString(), e);
        } else {
          responseCallback.onFailure(RealCall.this, e);
        }
      } catch (Throwable t) {
        cancel();
        if (!signalledCallback) {
          IOException canceledException = new IOException("canceled due to " + t);
          canceledException.addSuppressed(t);
          responseCallback.onFailure(RealCall.this, canceledException);
        }
        throw t;
      } finally {
        client.dispatcher().finished(this);
      }
    }
  }

最后拿到的responseBody在通过回调给调用者