Retrofit2源码解析02-创建Call

我们在获得了Retrofit对象后,通过create方法可以获得生成接口的代理对象。

ApiService service = retrofit.create(ApiService.class);  

来看create方法

public <T> T create(final Class<T> service) {
Utils.validateServiceInterface(service);
//如果validateEagerly为true,则进行预处理,提前创造一些MethodHandler对象在缓存中,默认为true。
if (validateEagerly) {
  eagerlyValidateMethods(service);
}
//返回一个动态代理对象
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
    new InvocationHandler() {
      private final Platform platform = Platform.get();

      @Override public Object invoke(Object proxy, Method method, 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);
        }
        if (platform.isDefaultMethod(method)) {
          return platform.invokeDefaultMethod(method, service, proxy, args);
        }
        ServiceMethod serviceMethod = loadServiceMethod(method);
        OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
        return serviceMethod.callAdapter.adapt(okHttpCall);
      }
    });
}  

首先调用了Utils.validateServiceInterface(service);

static <T> void validateServiceInterface(Class<T> service) {
    if (!service.isInterface()) {
      throw new IllegalArgumentException("API declarations must be interfaces.");
    }
    // Prevent API interfaces from extending other interfaces. This not only avoids a bug in
    // Android (http://b.android.com/58753) but it forces composition of API declarations which is
    // the recommended pattern.
    if (service.getInterfaces().length > 0) {
      throw new IllegalArgumentException("API interfaces must not extend other interfaces.");
    }
}  

可以看到,如果传入的Class不是接口,或者这个Class有继承自其它接口,则抛出异常。

再来看create方法中的Proxy.newProxyInstance,可以看到,新new了一个invocationHandler。主要来看InvocationHandler

new InvocationHandler() {
  private final Platform platform = Platform.get();

  @Override public Object invoke(Object proxy, Method method, Object... args)
      throws Throwable {
    //method.getDeclaringClass() 返回方法定义所在的类
    //如果method定义所在的类就是object,直接通过反射调用
    if (method.getDeclaringClass() == Object.class) {
      return method.invoke(this, args);
    }
    //只有Java8实现了这个方法,其它平台都是返回false
    if (platform.isDefaultMethod(method)) {
      return platform.invokeDefaultMethod(method, service, proxy, args);
    }
    //加载ServiceMethod (优先从缓存中获取)
    ServiceMethod serviceMethod = loadServiceMethod(method);
    //传入serviceMethod和args,创建OkHttpCall
    OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
    //会创建ExecutorCallbackCall,并传入OkHttpCall
    return serviceMethod.callAdapter.adapt(okHttpCall);
  }
});  

如果method定义所在的类就是object,直接通过反射进行调用。如果不是,则会通过loadServiceMethod加载serviceMethod。获取ServiceMethod之后,创建一个OkHttpCall,并传入到serviceMethod的callAdapter.adapt()。

先来看下loadServiceMethod,这个会优先从缓存中获取,如果获取为null,则新创建一个serviceMethod,并存储到缓存中。

ServiceMethod loadServiceMethod(Method method) {
    ServiceMethod result;
    synchronized (serviceMethodCache) {
      //优先从缓存中获取
      result = serviceMethodCache.get(method);
      if (result == null) {
        result = new ServiceMethod.Builder(this, method).build();
        serviceMethodCache.put(method, result);
      }
    }
    return result;
}  

来看下serviceMethod是怎么被创建的。可以看到,
1. 首先遍历获得合适的CallAdapter和responseConverter。
2. 遍历method的注解,对请求方式(GET,POST)进行解析
3. 遍历method传入参数的注解(@Query、@Part),进行解析

#

public ServiceMethod build() {
  //会遍历adapterFactories列表中存储的CallAdapter.Factory,通过get方法返回CallAdapter对象,判断并返回一个合适的CallAdapter。
  //(也就是通过addCallAdapterFactory进行添加的列表)
  callAdapter = createCallAdapter();
  //得到返回数据的真实类型
  responseType = callAdapter.responseType();
  //...
  //遍历converterFactories列表中存储的Converter.Factory,通过responseBodyConverter方法返回Converter方法,判断并返回一个合适的Converter用来转换对象。  
  //(也就是通过addConverterFactory进行添加的列表)
  responseConverter = createResponseConverter();
  //遍历method的注解,调用parseMethodAnnotation对请求方式(比如GET、POST)和请求地址进行解析
  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);
    }

    //对方法中的参数注解进行解析 (比如@Query、@Part)  
    Annotation[] parameterAnnotations = parameterAnnotationsArray[p];
    if (parameterAnnotations == null) {
      throw parameterError(p, "No Retrofit annotation found.");
    }

    parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);
  }
  //...
  return new ServiceMethod<>(this);
}

createCallAdapter和createResponseConverter的代码逻辑类似,以createCallAdapter为例。
首先会获取Type和注解数组,然后调用callAdapter,最终,通过Type和注解数组获取相应的CallAdapter,并返回。

private CallAdapter<?> createCallAdapter() {
  //获取method的Type (java反射)
  Type returnType = method.getGenericReturnType();
  //...
  //获取method的注解数组
  Annotation[] annotations = method.getAnnotations();
  try {
    return retrofit.callAdapter(returnType, annotations);
  } catch (RuntimeException e) {
    throw methodError(e, "Unable to create call adapter for %s", returnType);
  }
}

public CallAdapter<?> callAdapter(Type returnType, Annotation[] annotations) {
    return nextCallAdapter(null, returnType, annotations);
}

public CallAdapter<?> nextCallAdapter(CallAdapter.Factory skipPast, Type returnType,
  Annotation[] annotations) {
    checkNotNull(returnType, "returnType == null");
    checkNotNull(annotations, "annotations == null");

    int start = adapterFactories.indexOf(skipPast) + 1;
    for (int i = start, count = adapterFactories.size(); i < count; i++) {
        CallAdapter<?> adapter = adapterFactories.get(i).get(returnType, annotations, this);
        if (adapter != null) {
            return adapter;
        }
    }
}  

至此,ServiceMethod就初始化完毕了。

再来看之前InvocationHandler中的serviceMethod.callAdapter.adapt()

ServiceMethod serviceMethod = loadServiceMethod(method);
OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);

调用loadServiceMethod之后,会先创建一个OkHttpCall,这个的构造方法里面只是进行了赋值操作。

OkHttpCall(ServiceMethod<T> serviceMethod, Object[] args) {
    this.serviceMethod = serviceMethod;
    this.args = args;
}  

之后,会调用serviceMethod.callAdapter.adapt()
我们在前一篇文章里面讲过,serviceMethod.callAdapter是用作将OkHttp的call对象转化为需要的对象,比如默认的ExecutorCallAdapterFactory,又比如转化为RxJava的Observable的RxJavaCallAdapterFactory。

这里来看ExecutorCallAdapter.Factory

@Override public <R> Call<R> adapt(Call<R> call) {
    return new ExecutorCallbackCall<>(callbackExecutor, call);

}

可以看到新new了一个ExecutorCallbackCall

static final class ExecutorCallbackCall<T> implements Call<T> {
    final Executor callbackExecutor;
    final Call<T> delegate;

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

    @Override public void enqueue(final Callback<T> callback) {
      if (callback == null) throw new NullPointerException("callback == null");

      delegate.enqueue(new Callback<T>() {
        @Override public void onResponse(Call<T> call, final Response<T> response) {
          callbackExecutor.execute(new Runnable() {
            @Override public void run() {
              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(new Runnable() {
            @Override public void run() {
              callback.onFailure(ExecutorCallbackCall.this, t);
            }
          });
        }
      });
    }  

    //...
}  

可以看到ExecutorCallbackCall是对Call的封装,主要通过callbackExecutor(这个是在Retroft构建的时候创建的,android平台的默认的是MainThreadexecutor,主要是将runnable回调到主线程执行),在主线程中执行runnable。

而ExecutorCallbackCall继承自Retort的Call,enqueue中,会通过delegate.enqueue进行调用,这里的delegate是OkHttpCall。回调结果中,会去调用到主线程,然后通过callback进行回调。

总结

retrofit.create方法的内部会创建一个动态代理对象并返回,真正的执行者是这个动态代理对象。

  1. 如果method定义所在的类就是object,直接通过反射调用。
  2. 加载ServiceMethod(优先通过缓存)
    1. 会遍历并选用合适的callAdapter和responseConverter
      1. callAdapter:将Call对象转化的合适执行类,比如RxJavaCallAdapterFactory
      2. responseConverter: 转化数据对象,比如GsonConverterFactory
    2. 会解析method和method传参的注解,比如@Get、@Query
  3. 获得serviceMethod后,会创建OkHttpCall
  4. 调用serviceMethod.calladapter.adapt(okhttpcall),并返回Retroft的Call方法。

serviceMethod.calladapter.adapt深入

这里的calladapter可以自己设置,比如RxJavaCallAdapterFactory,这里以默认的ExecutorCallAdapterFactory为例。

当调用Retrot的Call的enqueue的时候,交由delegate这个okhttp代理对象执行,并在返回结果中,先回调到主线程,执行callback的相关方法。

其他

文中的Retrfot版本为Retrfot2.1.0

猜你喜欢

转载自blog.csdn.net/ethanco/article/details/78449338