Step1 创建Retrofit实例以下是一个简单的Retrofit使用流程,在源码分析中只关注一些流程上的东西,忽略细节陷入细节的话很容易晕,好吧细节我也没咋看懂。。。
先看看Retrofit中的一些变量
public final class Retrofit {
private final Map> serviceMethodCache = new ConcurrentHashMap<>();
//很明显就是一个用于生成Okhttp的Call实例的工厂
//后续会看到其实就是把OkhttpClient赋值给它
final okhttp3.Call.Factory callFactory;
//这就是上图中对应的.baseUrl("")这里传入了一个空字符串,当然实际项目中肯定不能这样
//这只是为了方便,Retrofit会把传入的字符传转为HttpUrl对象
final HttpUrl baseUrl;
//保存自定义和默认的转换器,把响应数据转为特定格式
final List converterFactories;
//保存自定义和默认的Call的适配器
final List callAdapterFactories;
//一个线程调度器
final @Nullable Executor callbackExecutor;
//一个标志位判断是否需求提前验证上图Api接口中的这些方法,并保存到map中
final boolean validateEagerly;
Retrofit(okhttp3.Call.Factory callFactory, HttpUrl baseUrl,
List converterFactories, List 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.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);
}
}
}
Retrofit.Builder().build()总结:在Builder()中Platform.get()–>findPlatform()–>new Android()这一个流程走下来主要就是关联具体的平台,至于初始化实例对象就是在Android()中标记的那三点在build中会去调用,具体的作用后续会用到
直接上代码
public Retrofit build() {
//baseUrl为null直接抛出异常
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new OkHttpClient();
}
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
List callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));
// Make a defensive copy of the converters.
List 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);
}
Step2 Retrofit.Create()Step1就到此结束,总的来说就是初始化一些实例并保存下来
publicT create(final Class 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
loadServiceMethodServiceMethod> loadServiceMethod(Method method) {
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.put(method, result);
}
}
return result;
}
abstract class ServiceMethod{ static ServiceMethod parseAnnotations(Retrofit retrofit, Method method) { RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method); // ......省略 return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory); } abstract @Nullable T invoke(Object[] args); }
RequestFactory.parseAnnotations先梳理下流程:
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 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 {
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
staticHttpServiceMethod 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 callAdapter = createCallAdapter(retrofit, method, adapterType, annotations); Type responseType = callAdapter.responseType(); //4、创建数据转换器 Converter responseConverter = createResponseConverter(retrofit, method, responseType); //5、retrofit.callFactory就是okhttpClient,在Retrofit...build()已经分析过 okhttp3.Call.Factory callFactory = retrofit.callFactory; if (!isKotlinSuspendFunction) { return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter); } else if (continuationWantsResponse) { return (HttpServiceMethod ) new SuspendForResponse<>(requestFactory, callFactory, responseConverter, (CallAdapter >) callAdapter); } else { return (HttpServiceMethod ) new SuspendForBody<>(requestFactory, callFactory, responseConverter, (CallAdapter >) 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++) {
CallAdapter, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this);
if (adapter != null) {
return adapter;
}
}
//省略...
}
invoke再次回顾loadServiceMethod这一套流程
1、解析方法、方法参数的注解
2、创建CallAdapter(Convert的创建和它差不多)
3、创建HttpServiceMethod的具体实现类的实例对象并返回
实际上callAdapter使用的就是一个适配器模式,把我们的请求转换一次实际上底层还是使用的是Okhttp call.enqueue那套,而具体的HttpServiceMethod则是在invoke中去做一些其它处理,毕竟协程的请求和Rx这些肯定还是有不同的地方
别忘了在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) new SuspendForResponse<>(requestFactory,
callFactory, responseConverter, (CallAdapter>) callAdapter);
} else {
//noinspection unchecked Kotlin compiler guarantees ReturnT to be Object.
return (HttpServiceMethod) new SuspendForBody<>(requestFactory,
callFactory, responseConverter, (CallAdapter>) 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 CallAdaptedextends HttpServiceMethod { private final CallAdapter callAdapter; CallAdapted(RequestFactory requestFactory, okhttp3.Call.Factory callFactory, Converter responseConverter, CallAdapter callAdapter) { super(requestFactory, callFactory, responseConverter); this.callAdapter = callAdapter; } @Override protected ReturnT adapt(Call call, Object[] args) { return callAdapter.adapt(call); } }
来看一下DefaultCallAdapterFactory的get()方法做了什么
@Override public @Nullable CallAdapter, ?> get(
return new CallAdapter
看下ExecutorCallbackCall,它实现了Retrofit的Call接口,到这里实际上就是loadServiceMethod(method).invoke(args != null ? args : emptyArgs)这段代码的终点了,它最终返回的是一个实现了Retrofit.Call的对象,这也说明了在上面的使用流程中fetchData后为什么还要调用enqueue()方法
static final class ExecutorCallbackCallStep3 call.enqueueimplements 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) { checkNotNull(callback, "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); } }); } }); } //省略... }
我们得到的call对象实际上就是一个ExecutorCallbackCall对象,当调用enqueue的时候会来到delegate.enqueue(…)中,delegate实际上是一个HttpCall对象,具体的网络请求是在HttpCall中执行的,这里需要结合HttpCall中的代码来看
//HttpCall @Override public void enqueue(final Callbackcallback) { 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 { 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 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(Callcall) { //在这里把httpCall封装到Observable中了,剩下的也就是RxJava的事情了 //不管怎样它最终还是会回到httpCall的enqueue中并且使用okhttp.call去进行网络请求 Observable > 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); }
Retrofit怎样支持kotlin协程的到目前为止,CallAdapter 怎么变成一个 RxJava2CallAdapter 以及它的具体调用,我们也就清楚了
还是回到HttpServiceMethod.parseAnnotations中来
staticHttpServiceMethod 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 . responseType = Utils.getParameterUpperBound(0, (ParameterizedType) responseType); //step2 continuationWantsResponse = true; } if (!isKotlinSuspendFunction) { return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter); } else if (continuationWantsResponse) { //step3 return (HttpServiceMethod ) new SuspendForResponse<>(requestFactory, callFactory, responseConverter, (CallAdapter >) callAdapter); } }
这里精简了代码直接看最主要的
1、step1在RequestFactory.parseAnnotations中已经解释过了,如果方法是协程suspend那么会被置位true
2、continuationWantsResponse置为true
3、HttpServiceMethod的具体实例为SuspendForResponse
invoke方法都还是调用的HttpServiceMethod中的invoke,这个之前就说过,这里直接来看SuspendForResponse的adapt方法
static final class SuspendForResponseextends HttpServiceMethod { private final CallAdapter > callAdapter; SuspendForResponse(RequestFactory requestFactory, okhttp3.Call.Factory callFactory, Converter responseConverter, CallAdapter > callAdapter) { super(requestFactory, callFactory, responseConverter); this.callAdapter = callAdapter; } @Override protected Object adapt(Call call, Object[] args) { call = callAdapter.adapt(call); Continuation > continuation = (Continuation >) args[args.length - 1]; try { // step3 return KotlinExtensions.awaitResponse(call, continuation); } catch (Exception e) { return KotlinExtensions.yieldAndThrow(e, continuation); } } }
准备好了后会调用KotlinExtensions.awaitResponse(call, continuation)
suspend funContinuationCall .awaitResponse(): Response { return suspendCancellableCoroutine { continuation -> continuation.invokeOnCancellation { cancel() } enqueue(object : Callback { override fun onResponse(call: Call , response: Response ) { continuation.resume(response) } override fun onFailure(call: Call , t: Throwable) { continuation.resumeWithException(t) } }) } }
这里解释一下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的支持



