我们在获得了Retrofit对象后,通过create方法可以获得生成接口的代理对象。
ApiService service = retrofit.create(ApiService.class);
来看create方法
public T create(final Class 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 void validateServiceInterface(Class 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 serviceMethod, Object[] args) {
this.serviceMethod = serviceMethod;
this.args = args;
}
之后,会调用serviceMethod.callAdapter.adapt()
。
我们在前一篇文章里面讲过,serviceMethod.callAdapter是用作将OkHttp的call对象转化为需要的对象,比如默认的ExecutorCallAdapterFactory,又比如转化为RxJava的Observable的RxJavaCallAdapterFactory。
这里来看ExecutorCallAdapter.Factory
@Override public Call adapt(Call call) {
return new ExecutorCallbackCall<>(callbackExecutor, call);
}
可以看到新new了一个ExecutorCallbackCall
static final class ExecutorCallbackCall implements Call {
final Executor callbackExecutor;
final Call delegate;
ExecutorCallbackCall(Executor callbackExecutor, Call delegate) {
this.callbackExecutor = callbackExecutor;
this.delegate = delegate;
}
@Override public void enqueue(final Callback callback) {
if (callback == null) throw new NullPointerException("callback == null");
delegate.enqueue(new Callback() {
@Override public void onResponse(Call call, final Response 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 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方法的内部会创建一个动态代理对象并返回,真正的执行者是这个动态代理对象。
这里的calladapter可以自己设置,比如RxJavaCallAdapterFactory,这里以默认的ExecutorCallAdapterFactory为例。
当调用Retrot的Call的enqueue的时候,交由delegate这个okhttp代理对象执行,并在返回结果中,先回调到主线程,执行callback的相关方法。
文中的Retrfot版本为Retrfot2.1.0