简单使用流程
以下是一个简单的Retrofit使用流程,在源码分析中只关注一些流程上的东西,忽略细节陷入细节的话很容易晕,好吧细节我也没咋看懂。。。
Step1 创建Retrofit实例
先看看Retrofit中的一些变量
public final class Retrofit {
private final Map<Method, ServiceMethod<?>> serviceMethodCache = new ConcurrentHashMap<>();
//很明显就是一个用于生成Okhttp的Call实例的工厂
//后续会看到其实就是把OkhttpClient赋值给它
final okhttp3.Call.Factory callFactory;
//这就是上图中对应的.baseUrl("")这里传入了一个空字符串,当然实际项目中肯定不能这样
//这只是为了方便,Retrofit会把传入的字符传转为HttpUrl对象
final HttpUrl baseUrl;
//保存自定义和默认的转换器,把响应数据转为特定格式
final List<Converter.Factory> converterFactories;
//保存自定义和默认的Call的适配器
final List<CallAdapter.Factory> callAdapterFactories;
//一个线程调度器
final @Nullable Executor callbackExecutor;
//一个标志位判断是否需求提前验证上图Api接口中的这些方法,并保存到map中
final boolean validateEagerly;
Retrofit(okhttp3.Call.Factory callFactory, HttpUrl baseUrl,
List<Converter.Factory> converterFactories, List<CallAdapter.Factory> callAdapterFactories,
@Nullable Executor callbackExecutor, boolean validateEagerly) {
this.callFactory = callFactory;
this.baseUrl = baseUrl;
this.converterFactories = converterFactories; // Copy+unmodifiable at call site.
this.callAdapterFactories = callAdapterFactories; // Copy+unmodifiable at call site.
this.callbackExecutor = callbackExecutor;
this.validateEagerly = validateEagerly;
}
Retrofit.Builder()
首先来到Retrofit.Builder()中:截取部分代码片段
在Builder()中的代码很简单Platform.get()方法会来到Platform类的findPlatform()方法,方法名其实已经很明确了此方法和平台有关
if (Build.VERSION.SDK_INT != 0) {
return new Android();
}
在Android开发中一定会调用到new Android()生成一个Android类型的实例,当然此实例对象是继承自Platform,来看一下它又做了什么
static class Android extends Platform {
@IgnoreJRERequirement // Guarded by API check.
@Override boolean isDefaultMethod(Method method) {
if (Build.VERSION.SDK_INT < 24) {
return false;
}
return method.isDefault();
}
@Override public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
//1:这里会返回一个默认的CallAdapter实例,具体后面分析
@Override List<? extends CallAdapter.Factory> defaultCallAdapterFactories(
@Nullable Executor callbackExecutor) {
if (callbackExecutor == null) throw new AssertionError();
DefaultCallAdapterFactory executorFactory = new DefaultCallAdapterFactory(callbackExecutor);
return Build.VERSION.SDK_INT >= 24
? asList(CompletableFutureCallAdapterFactory.INSTANCE, executorFactory)
: singletonList(executorFactory);
}
@Override int defaultCallAdapterFactoriesSize() {
return Build.VERSION.SDK_INT >= 24 ? 2 : 1;
}
//2:这里返回一个默认的数据转换器
@Override List<? extends Converter.Factory> defaultConverterFactories() {
return Build.VERSION.SDK_INT >= 24
? singletonList(OptionalConverterFactory.INSTANCE)
: Collections.<Converter.Factory>emptyList();
}
@Override int defaultConverterFactoriesSize() {
return Build.VERSION.SDK_INT >= 24 ? 1 : 0;
}
//3:用于线程调度
static class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
@Override public void execute(Runnable r) {
handler.post(r);
}
}
}
总结:在Builder()中Platform.get()–>findPlatform()–>new Android()这一个流程走下来主要就是关联具体的平台,至于初始化实例对象就是在Android()中标记的那三点在build中会去调用,具体的作用后续会用到
Retrofit.Builder().build()
直接上代码
public Retrofit build() {
//baseUrl为null直接抛出异常
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
/**
*注意:这里就把this.callFactory赋值给Call.Factory了简单看一下它的初始化流程:
* public Builder client(OkHttpClient client) {
* return callFactory(checkNotNull(client, "client == null"));}
*
* public Builder callFactory(okhttp3.Call.Factory factory) {
* this.callFactory = checkNotNull(factory, "factory == null");
* return this;}
* 从这两个方法就可以看出了callFactory就是一个OkhttpClient,即Call.Factory
* 就是OkhttpClient,还记得Okhttp中的call怎么创建出来的吗?就是通过
* OkHttpClient的newCall方法创建的,从这里大概能猜出为什么经常听到Retrofit底
* 层是使用的Okhttp了
*/
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new OkHttpClient();
}
/**
* 这里就是初始化Retrofit的线程调度器了,如果我们没有手动设置的话就会使用
* platform中初始化的那个线程调度器即:MainThreadExecutor
*/
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
/**
* 后续的代码就是把默认的数据转换器以及call的适配器全部保存到list中,包括自己设置
* 以及Retrofit默认的
*/
List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));
// Make a defensive copy of the converters.
List<Converter.Factory> converterFactories = new ArrayList<>(
1 + this.converterFactories.size() + platform.defaultConverterFactoriesSize());
// Add the built-in converter factory first. This prevents overriding its behavior but also
// ensures correct behavior when using converters that consume all types.
converterFactories.add(new BuiltInConverters());
converterFactories.addAll(this.converterFactories);
converterFactories.addAll(platform.defaultConverterFactories());
return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
}
Step1就到此结束,总的来说就是初始化一些实例并保存下来
Step2 Retrofit.Create()
public <T> T create(final Class<T> service) {
Utils.validateServiceInterface(service);
//这里在Retrofit的变量就已经分析了
if (validateEagerly) {
eagerlyValidateMethods(service);
}
return (T) 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);
}
//如果是默认方法(比如 Java8 ),就执行 platform 的默认方法。否则执行
// loadServiceMethod方法的invoke方法
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
}
});
}
这里一目了然核心就是一个动态代理,回到最开始的使用流程来看当调用api.fetchData方法之后会来到InvocationHandler的invoke中并最终调用loadServiceMethod方法,主要看最后一行loadServiceMethod(method).invoke(args != null ? args : emptyArgs),这里分两部分来看loadServiceMethod和invoke
loadServiceMethod
ServiceMethod<?> loadServiceMethod(Method method) {
ServiceMethod<?> result = serviceMethodCache.get(method);
if (result != null) return result;
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
/**
* 该方法核心就是为了获取ServiceMethod实例,以method为key首先在map中取
* 如果没有就通过parseAnnotations去创建,并把已经构造出来的Retrofit实例
* 和method传进去
*/
result = ServiceMethod.parseAnnotations(this, method);
serviceMethodCache.put(method, result);
}
}
return result;
}
/**
* RequestFactory.parseAnnotations(retrofit, method)主要是解析方法的注解
* 和参数的注解并保存下来
*
* HttpServiceMethod.parseAnnotations主要是创建CallAdapter即请求的适配器
* 以及Convert即数据转换器
*
* 最终会返回一个HttpServiceMethod的具体实现类的实例对象
* 具体代码后面再分析
*/
abstract class ServiceMethod<T> {
static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);
// ......省略
return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
}
abstract @Nullable T invoke(Object[] args);
}
先梳理下流程:
1、首先Retrofit.Builder().build()这中间会去初始化一些实例比如默认的CallAdapter.Factory以及默认的数据转换器并保存,当然也会保存我们自己设置的,还会把OkhttpClient赋值给retrofit的Call.Factory变量最后创建Retrofit实例
2、通过动态代理在create中返回一个Api的proxy对象
3、当使用api.fetchData的时候来到invocationHandler的invoke中并最终调用loadServiceMethod(…).invoke(…)
4、创建一个HttpServiceMethod的具体实现类的实例对象,在创建的过程中首先通过RequestFactory.parseAnnotations去解析方法以及方法参数的注解,其次在HttpServiceMethod.parseAnnotations中还会创建CallAdapter、Convert
5、调用HttpServiceMethod的具体实例的invoke方法
RequestFactory.parseAnnotations
RequestFactory build() {
for (Annotation annotation : methodAnnotations) {
//这里主要是解析method的注解如GET、POST等,获取其中的值并保存这里就是
//{pageNo}/fetch 这部分很简单感兴趣可以看下
parseMethodAnnotation(annotation);
}
//省略部分代码...
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);
}
//省略部分代码...
return new RequestFactory(this);
}
private @Nullable ParameterHandler<?> parseParameter(
int p, Type parameterType, @Nullable Annotation[] annotations, boolean allowContinuation) {
ParameterHandler<?> result = null;
//这里主要是解析method参数的注解
if (annotations != null) {
for (Annotation annotation : annotations) {
ParameterHandler<?> annotationAction =
parseParameterAnnotation(p, parameterType, annotations, annotation);
if (annotationAction == null) {
continue;
}
if (result != null) {
throw parameterError(method, p,
"Multiple Retrofit annotations found, only one allowed.");
}
result = annotationAction;
}
}
if (result == null) {
if (allowContinuation) {
try {
/**
* 注意这里如果我们Api接口里面使用的是协程那么会把isKotlinSuspendFunction
* 置为true,协程中的suspend方法转为java代码的时候就是这个Continuation类型
*/
if (Utils.getRawType(parameterType) == Continuation.class) {
isKotlinSuspendFunction = true;
return null;
}
} catch (NoClassDefFoundError ignored) {
}
}
throw parameterError(method, p, "No Retrofit annotation found.");
}
return result;
}
HttpServiceMethod.parseAnnotations
static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
Retrofit retrofit, Method method, RequestFactory requestFactory) {
boolean isKotlinSuspendFunction = requestFactory.isKotlinSuspendFunction;
boolean continuationWantsResponse = false;
boolean continuationBodyNullable = false;
Annotation[] annotations = method.getAnnotations();
Type adapterType;
//1、这里就是在解析method参数注解的时候设置的,如果使用了协程那么会置为true
if (isKotlinSuspendFunction) {
Type[] parameterTypes = method.getGenericParameterTypes();
Type responseType = Utils.getParameterLowerBound(0,
(ParameterizedType) parameterTypes[parameterTypes.length - 1]);
if (getRawType(responseType) == Response.class && responseType instanceof ParameterizedType) {
responseType = Utils.getParameterUpperBound(0, (ParameterizedType) responseType);
//2、continuationWantsResponse赋值为true
continuationWantsResponse = true;
}
adapterType = new Utils.ParameterizedTypeImpl(null, Call.class, responseType);
annotations = SkipCallbackExecutorImpl.ensurePresent(annotations);
} else {
adapterType = method.getGenericReturnType();
}
//3、这里就是创建CallAdapter
CallAdapter<ResponseT, ReturnT> callAdapter =
createCallAdapter(retrofit, method, adapterType, annotations);
Type responseType = callAdapter.responseType();
//4、创建数据转换器
Converter<ResponseBody, ResponseT> responseConverter =
createResponseConverter(retrofit, method, responseType);
//5、retrofit.callFactory就是okhttpClient,在Retrofit...build()已经分析过
okhttp3.Call.Factory callFactory = retrofit.callFactory;
/**
* 6、从这里就开始创建HttpServiceMethod的具体实现类了
* 不是协程suspend的话就返回CallAdapted
* 是协程就返回SuspendForResponse
*/
if (!isKotlinSuspendFunction) {
return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
} else if (continuationWantsResponse) {
return (HttpServiceMethod<ResponseT, ReturnT>) new SuspendForResponse<>(requestFactory,
callFactory, responseConverter, (CallAdapter<ResponseT, Call<ResponseT>>) callAdapter);
} else {
return (HttpServiceMethod<ResponseT, ReturnT>) new SuspendForBody<>(requestFactory,
callFactory, responseConverter, (CallAdapter<ResponseT, Call<ResponseT>>) callAdapter,
continuationBodyNullable);
}
}
注意
1、创建的CallAdapter可能是系统默认的可能是我们自己设置的如RxJava3CallAdapterRxJava3CallAdapter是从RxJava3CallAdapterFactory中get()出来的,而RxJava3CallAdapterFactory就是通过addCallAdapterFactory(RxJava3CallAdapterFactory.create())设置的
2、通过判断协程suspend去创建不同的HttpServiceMethod的具体实现类
下面来看一下CallAdapter的创建流程通过一系列调用最终会来到nextCallAdapter方法中:
public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType,
Annotation[] annotations) {
checkNotNull(returnType, "returnType == null");
checkNotNull(annotations, "annotations == null");
int start = callAdapterFactories.indexOf(skipPast) + 1;
for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
/**
* callAdapterFactories在之前就介绍过,这里根据returnType去寻找CallAdapter
* 比如:我们在Api中的fetchData returnType 类型为 Single,那么返回的就是 RxJava2CallAdapterFactory 所获取的 CallAdapter
*
* 若returnType是Call<xxxBean>返回的就是默认的CallAdapter,即DefaultCallAdapterFactory.get获取到的
* 而它也在Retrofit..build()中就已经设置到callAdapterFactories中了
*/
CallAdapter<?, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this);
if (adapter != null) {
return adapter;
}
}
//省略...
}
再次回顾loadServiceMethod这一套流程
1、解析方法、方法参数的注解
2、创建CallAdapter(Convert的创建和它差不多)
3、创建HttpServiceMethod的具体实现类的实例对象并返回
实际上callAdapter使用的就是一个适配器模式,把我们的请求转换一次实际上底层还是使用的是Okhttp call.enqueue那套,而具体的HttpServiceMethod则是在invoke中去做一些其它处理,毕竟协程的请求和Rx这些肯定还是有不同的地方
invoke
别忘了在loadServiceMethod后紧跟着就调用了invoke方法,现在来看一下,
if (!isKotlinSuspendFunction) {
return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
} else if (continuationWantsResponse) {
//noinspection unchecked Kotlin compiler guarantees ReturnT to be Object.
return (HttpServiceMethod<ResponseT, ReturnT>) new SuspendForResponse<>(requestFactory,
callFactory, responseConverter, (CallAdapter<ResponseT, Call<ResponseT>>) callAdapter);
} else {
//noinspection unchecked Kotlin compiler guarantees ReturnT to be Object.
return (HttpServiceMethod<ResponseT, ReturnT>) new SuspendForBody<>(requestFactory,
callFactory, responseConverter, (CallAdapter<ResponseT, Call<ResponseT>>) callAdapter,
continuationBodyNullable);
}
在HttpServiceMethod.parseAnnotations中最终通过isKotlinSuspendFunction创建了不同的HttpServiceMethod实例,默认情况下是CallAdapted,来看下它的处理,实际上不管是哪种实例,invoke都调用的是HttpServiceMethod的invoke,子类都只是重写了adapt方法。
在这里我们看到创建了一个Call对象,这个call对象是Retrofit中的,注意这里的参数有requestFactory, args, callFactory, responseConverter,requestFactory中封装了方法和方法参数的各种注解,args是反复的参数,callFactory实际上就是个OkhttpClient,responseConverter则是数据转换器。
下面先来看下adapt做了什么:
static final class CallAdapted<ResponseT, ReturnT> extends HttpServiceMethod<ResponseT, ReturnT> {
private final CallAdapter<ResponseT, ReturnT> callAdapter;
CallAdapted(RequestFactory requestFactory, okhttp3.Call.Factory callFactory,
Converter<ResponseBody, ResponseT> responseConverter,
CallAdapter<ResponseT, ReturnT> callAdapter) {
super(requestFactory, callFactory, responseConverter);
this.callAdapter = callAdapter;
}
/**
* invoke会来到这里,而这里又调用的是callAdapter.adapt并把httpCall传进去了
* 我们现在讨论的是默认的情况,即addCallAdapterFactory这些都没设置
* 并且返回参数也是Call<xxxBean>,所以这里的callAdapter是从DefaultCallAdapterFactory的get()中获取的
*/
@Override protected ReturnT adapt(Call<ResponseT> call, Object[] args) {
return callAdapter.adapt(call);
}
}
来看一下DefaultCallAdapterFactory的get()方法做了什么
@Override public @Nullable CallAdapter<?, ?> get(
/**
* 这里直接new了一个CallAdapter的实例
*/
return new CallAdapter<Object, Call<?>>() {
@Override public Type responseType() {
return responseType;
}
/**
* adapt最终又会来到这里并创建了ExecutorCallbackCall,注意参数处了传进来的HttpCall外还有线程调度器executor
*/
@Override public Call<Object> adapt(Call<Object> call) {
return executor == null
? call
: new ExecutorCallbackCall<>(executor, call);
}
};
}
看下ExecutorCallbackCall,它实现了Retrofit的Call接口,到这里实际上就是loadServiceMethod(method).invoke(args != null ? args : emptyArgs)这段代码的终点了,它最终返回的是一个实现了Retrofit.Call的对象,这也说明了在上面的使用流程中fetchData后为什么还要调用enqueue()方法
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) {
checkNotNull(callback, "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);
}
});
}
});
}
//省略...
}
Step3 call.enqueue
我们得到的call对象实际上就是一个ExecutorCallbackCall对象,当调用enqueue的时候会来到delegate.enqueue(…)中,delegate实际上是一个HttpCall对象,具体的网络请求是在HttpCall中执行的,这里需要结合HttpCall中的代码来看
//HttpCall
@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;
call = rawCall;
failure = creationFailure;
if (call == null && failure == null) {
try {
/**
* 1、创建Okhttp.call,在createRawCall中还会根据requestFactory去创建okhttp3.Request
* requestFactory中包含了请求的各种注解信息,毕竟只有call没有request肯定是不行的晒
*/
call = rawCall = createRawCall();
} catch (Throwable t) {
throwIfFatal(t);
failure = creationFailure = t;
}
}
}
if (failure != null) {
callback.onFailure(this, failure);
return;
}
if (canceled) {
call.cancel();
}
// step2
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
}
}
});
}
注意step2,在DefaultCallAdapterFactory.ExecutorCallbackCall的enqueue方法暂且命名为enqueue1这里为enqueue2,执行的enqueue1实际上会来到enqueue2中,因为enqueue1中的call实际上是HttpCall类型,这里接收一个CallBack对象用于请求回调,我们知道网络请求肯定不能在主线程,这个时候一直说的excutor线程调度器就起作用了,当执行callback.onResponse或者callback.onFailure又会回到enqueue1中去,再利用excutor把线程给切会主线程中
到此一套完整的流程就结束了
CallAdapter的替换过程
之前讨论的是默认情况现在假如我们这样使用
我们通过addCallAdapterFactory添加了RxJava3CallAdapterFactory并且方法searchAndroidRepos返回的是Observable类型,现在重新回到HttpServiceMethod.parseAnnotations中直接看核心代码
最终还是来到retrofit的nextCallAdapter方法中,根据returnType Observable这个时候得到就是RxJava3CallAdapterFactory.get()返回的CallAdapter即:RxJava3CallAdapter,当然此时loadServiceMethod返回的HttpServiceMethod的具体实例还是CallAdapted,所以这个时候invoke最终会来到RxJava3CallAdapter的adapt方法中:
@Override
public Object adapt(Call<R> call) {
//在这里把httpCall封装到Observable中了,剩下的也就是RxJava的事情了
//不管怎样它最终还是会回到httpCall的enqueue中并且使用okhttp.call去进行网络请求
Observable<Response<R>> responseObservable =
isAsync ? new CallEnqueueObservable<>(call) : new CallExecuteObservable<>(call);
Observable<?> observable;
if (isResult) {
observable = new ResultObservable<>(responseObservable);
} else if (isBody) {
observable = new BodyObservable<>(responseObservable);
} else {
observable = responseObservable;
}
if (scheduler != null) {
observable = observable.subscribeOn(scheduler);
}
if (isFlowable) {
return observable.toFlowable(BackpressureStrategy.LATEST);
}
if (isSingle) {
return observable.singleOrError();
}
if (isMaybe) {
return observable.singleElement();
}
if (isCompletable) {
return observable.ignoreElements();
}
return RxJavaPlugins.onAssembly(observable);
}
到目前为止,CallAdapter 怎么变成一个 RxJava2CallAdapter 以及它的具体调用,我们也就清楚了
Retrofit怎样支持kotlin协程的
还是回到HttpServiceMethod.parseAnnotations中来
static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
Retrofit retrofit, Method method, RequestFactory requestFactory) {
boolean isKotlinSuspendFunction = requestFactory.isKotlinSuspendFunction;
boolean continuationWantsResponse = false;
// step1
if (isKotlinSuspendFunction) {
Type[] parameterTypes = method.getGenericParameterTypes();
Type responseType = Utils.getParameterLowerBound(0,
(ParameterizedType) parameterTypes[parameterTypes.length - 1]);
if (getRawType(responseType) == Response.class && responseType instanceof ParameterizedType) {
// Unwrap the actual body type from Response<T>.
responseType = Utils.getParameterUpperBound(0, (ParameterizedType) responseType);
//step2
continuationWantsResponse = true;
}
if (!isKotlinSuspendFunction) {
return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
} else if (continuationWantsResponse) {
//step3
return (HttpServiceMethod<ResponseT, ReturnT>) new SuspendForResponse<>(requestFactory,
callFactory, responseConverter, (CallAdapter<ResponseT, Call<ResponseT>>) callAdapter);
}
}
这里精简了代码直接看最主要的
1、step1在RequestFactory.parseAnnotations中已经解释过了,如果方法是协程suspend那么会被置位true
2、continuationWantsResponse置为true
3、HttpServiceMethod的具体实例为SuspendForResponse
invoke方法都还是调用的HttpServiceMethod中的invoke,这个之前就说过,这里直接来看SuspendForResponse的adapt方法
static final class SuspendForResponse<ResponseT> extends HttpServiceMethod<ResponseT, Object> {
private final CallAdapter<ResponseT, Call<ResponseT>> callAdapter;
SuspendForResponse(RequestFactory requestFactory, okhttp3.Call.Factory callFactory,
Converter<ResponseBody, ResponseT> responseConverter,
CallAdapter<ResponseT, Call<ResponseT>> callAdapter) {
super(requestFactory, callFactory, responseConverter);
this.callAdapter = callAdapter;
}
@Override protected Object adapt(Call<ResponseT> call, Object[] args) {
/**
* step1
* 注意这里的callAdapter还是默认的callAdapter即从DefaultCallAdapterFactory.get获取的
* 所以这里的call实际上就是ExecutorCallbackCall
*/
call = callAdapter.adapt(call);
/**
* step2
* args[args.length - 1]取最后一个参数
* 强转为Continuation类型
*/
Continuation<Response<ResponseT>> continuation =
(Continuation<Response<ResponseT>>) args[args.length - 1];
try {
// step3
return KotlinExtensions.awaitResponse(call, continuation);
} catch (Exception e) {
return KotlinExtensions.yieldAndThrow(e, continuation);
}
}
}
准备好了后会调用KotlinExtensions.awaitResponse(call, continuation)
suspend fun <T : Any> Call<T>.awaitResponse(): Response<T> {
return suspendCancellableCoroutine { continuation ->
continuation.invokeOnCancellation {
cancel()
}
/**
* 这里用到了kotlin的扩展函数的特性,然后调用了call的enqueue方法
*/
enqueue(object : Callback<T> {
override fun onResponse(call: Call<T>, response: Response<T>) {
continuation.resume(response)
}
override fun onFailure(call: Call<T>, t: Throwable) {
continuation.resumeWithException(t)
}
})
}
}
Continuation
这里解释一下KotlinExtensions.awaitResponse(call, continuation)这段代码
@GET("search/repositories?sort=stars&q=Android")
suspend fun searchAndroidRepos2(
@Query("per_page") per_page: Int,
@Query("page") page: Int
): RepoResponse
这两段代码和KotlinExtensions.awaitResponse的情况很相似都是java调用kotlin suspend方法的代码,awaitResponse方法没有参数为什么java调用需要传递两个参数
1、awaitResponse是Call的一个扩展方法java调用时候需要把Call对象传进去
2、java调用kotlin suspend方法的代码,需要在最后传递一个Continuation类型的参数
以上就是Retrofit对kotlin的支持