基本用法
val retrofit = Retrofit.Builder()
.baseUrl("baseurl")
.callFactory(xxx)
.addCallAdapterFactory(xxx)
.addConverterFactory(xxx)
.build()
val api = retrofit.creat(Api::class.java)
api.getName("1").enqueue(object:Callback<UserName>{
override fun onFailure(call: Call<UserName>, t: Throwable) {
t.printStackTrace()
}
override fun onResponse(call: Call<UserName>, response: Response<UserName>) {
do something
}
}
interface Api {
@GET("users/{userid}")
fun getName(@Path("userid") id: String): Call<UserName>
}
基本用法就不赘述了,下面分析其源码。
源码分析
val retrofit = Retrofit.Builder(). ... .build()这段代码就是通过链式调用实例化retrofit,并根据需要传入一些初始化参数,比如设置baseUrl,添加GsonConverterFactory RxJava3CallAdapterFactory等。
为了便于理解,我们从后面往前看起,从enqueue(object : Callback<ResponseBody>{...}入手。点进enqueue方法:
public interface Call<T> extends Cloneable {
...
void enqueue(Callback<T> callback);
...
}
可以看到是接口Call中的方法,这个Call很明显就是我们创建的Api中的方法返回的。我们创建的Api也是接口,所以必然有其实现类,而api实例是通过retrofit.create(Api::class.java)方法返回的,所以可以推断api是在create方法中实现的,我们重点看一下这个create方法。
重点一:Retrofit.create 方法
public final class Retrofit{
...
public <T> T create(final Class<T> service) {
validateServiceInterface(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 {
// 如果这个方法是Object中的方法,就不做处理,按原方法执行
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);
}
});
}
①处是对传入的Class进行合法性检验,不是重点,这里就不往里看了,重点看下面。这里Retrofit是采用动态代理来返回Api的实例,当外部调用Api中的方法时,代理类会拦截该方法,获取该方法的信息,并执行invoke方法,可以看到invoke方法有一个method参数,这个参数就是外部当前正在调用的Api中的方法。Api中的每个方法都是一个请求,将method作为参数传入loadServiceMethod方法,loadServiceMethod返回一个ServiceMethod实例,然后调用其invoke方法(动态代理类和ServiceMethod有同名方法invoke,为了便于区分,下文中将代理类的invoke方法称为P.invoke,将ServiceMethod的invoke方法称为M.invoke)。下面来看看这两个方法。
重点二:loadServiceMethod(method).invoke(args)方法
先看前半部分loadServiceMethod(method)方法:
public final class Retrofit{
private final Map<Method, ServiceMethod<?>> serviceMethodCache = new ConcurrentHashMap<>();
...
ServiceMethod<?> 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;
}
}
该方法返回的是ServiceMethod对象,可以看到Retrofit中维护了一个serviceMethodCache,它是一个Map,用来缓存ServiceMethod。为什么要缓存它我们后面说,可以先思考一下。根据传入的method从缓存map中获取ServuceMothod,如果ServiceMethod不存在,就调用ServiceMethod.parseAnnotations(this, method)方法返回一个实例,并put进缓存map里。点进ServiceMethod.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);
}
记住①处的RequestFactory,后面我们会说到。②处是一些异常处理,不关心,直接看③,这里调用的是HttpServiceMethod.parseAnnotations方法。我们注意到ServiceMethod是个抽象类,在④处定义了M.invoke抽象方法。点进HttpServiceMethod.parseAnnotations方法:
abstract class HttpServiceMethod<ResponseT, ReturnT> extends ServiceMethod<ReturnT> {
static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(Retrofit retrofit, Method method, RequestFactory requestFactory) {
...
if (!isKotlinSuspendFunction) { // ①
return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
} else ...
}
@Override
final @Nullable ReturnT invoke(Object[] args) {
Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
return adapt(call, args);
}
}
发现HttpServiceMethod也是个抽象类,①处判断的是是否是kotlin的挂起函数,这里暂不分析kotlin,只看java。可以看到parseAnnotations方法最终返回的是CallAdapted对象,那么这个CallAdapted就是HttpServiceMethod的实现类了,我们稍后看CallAdapted,先来看看M.invoke方法是如何实现的。在M.invoke方法中,创建了Call类型的变量call并且用new OkHttpCall进行了实例化,这个Call类型就是我们定义Api接口时方法的返回值,而OkHttpCall就是Call的实现类。将call作为参数传入了adapt方法,继续追踪adapt方法:
abstract class HttpServiceMethod<ResponseT, ReturnT> extends ServiceMethod<ReturnT> {
...
protected abstract @Nullable ReturnT adapt(Call<ResponseT> call, Object[] args);
...
}
发现adapt方法也是个抽象方法,那么它的实现肯定是在HttpServiceMethod的实现类CallAdapted里了。现在再返回来看CallAdapted:
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;
}
@Override
protected ReturnT adapt(Call<ResponseT> call, Object[] args) {
return callAdapter.adapt(call);
}
}
发现adapt方法内部直接调用了callAdapter.adapt(call)方法,继续跟进:
public interface CallAdapter<R, T> {
...
T adapt(Call<R> call);
abstract class Factory {
public abstract @Nullable CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit);
}
...
}
发现CallAdapter是一个接口,内部除了定义了adapt方法,还创建了抽象类Factory,CallAdapter的实例就是由Factory中的get方法返回的。CallAdapted类中的callAdapter追踪到最后是由从Retrofit中的callAdapterFactories集合里取到的CallAdapter.Factory的实现类中的get方法返回的,该实现类是由开头实例化Retrofit时通过addCallAdapterFactory(xxx)方法传入的(比如我们经常使用的RxJava3CallAdapterFactory,它就是CallAdapter.Factory的一个实现类,作用是支持Rxjava式请求),如果没有调用这个方法传入Factory实现类,那么就会使用默认的DefaultCallAdapterFactory(这里就不展示追踪过程了,有兴趣可以自己去看一下源码)。看一下DefaultCallAdapterFactory是如何实现get方法的:
final class DefaultCallAdapterFactory extends Factory {
@Nullable
private final Executor callbackExecutor;
DefaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
this.callbackExecutor = callbackExecutor;
}
@Nullable
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
...
return new CallAdapter<Object, Call<?>>() {
public Type responseType() {
return responseType;
}
public Call<Object> adapt(Call<Object> call) {
return (Call)(executor == null ? call : new DefaultCallAdapterFactory.ExecutorCallbackCall(executor, call));
}
};
}
}
可以看到get方法最终返回了一个CallAdapter的匿名实现类,adapt方法实现逻辑是判断executor如果是null就直接将参数call返回(还记得这个call是什么吗?往上面翻,adapt方法是在M.invoke方法中被调用的,M.invoke方法中创建了一个OkHttpCall的实例传入了adapt方法中,所以这里的参数call就是OkHttCall对象),否则就new一个ExecutorCallbackCall对象返回。再来看看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;
}
public void enqueue(final Callback<T> callback) {
Objects.requireNonNull(callback, "callback == null");
this.delegate.enqueue(new Callback<T>() { ... }
}
}
ExecutorCallbackCall实现了Call接口,并且持有了一个Call类型的变量delegate,而通过①处构造方法可知,这个delegate就是上面adapt方法的call参数,也就是OkHttCall实例,ExecutorCallbackCall实际上就是OkHttpCall的代理类,其enqueue方法里面实际上还是调用的OkhttpCall类中的enqueue方法。至此我们可以断定具体的网络请求操作就是在OkHttpCall中实现的。
现在我们来回顾一下流程:先创建Retrofit实例,然后调用Retrofit的create方法,将我们定义的Api接口的class作为参数传入,create方法里使用动态代理返回Api的代理类,当外部调用Api中的方法时,代理类会拦截Api方法,调用自己的P.invoke方法,将Api中的方法包装成ServiceMethod类,并调用M.invoke方法(M.invoke方法具体实现是在HttpServiceMethod中),M.invoke方法得到的是Call的实现类OkHttpCall(或者其代理类ExecutorCallbackCall),所以我们调用api中的方法(例如文章开头的api.getName("1"))拿到的是一个OkHttpCall实例,再调用enqueue就会由OkHttpCall进行具体的网络请求操作了。
重点三:OkHttpCall(一)
上面分析到具体的网络请求操作是在OkHttpCall中实现的,那么就来看看OkHttpCall做了什么。从它实例化的地方入手,也就是M.invoke方法中:
abstract class HttpServiceMethod<ResponseT, ReturnT> extends ServiceMethod<ReturnT> {
private final RequestFactory requestFactory;
private final okhttp3.Call.Factory callFactory;
private final Converter<ResponseBody, ResponseT> responseConverter;
@Override
final @Nullable ReturnT invoke(Object[] args) {
Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
return adapt(call, args);
}
}
可以看到创建OkHttpCall对象时传入了四个参数,我们需要知道这四个参数都是什么。其中args是通过M.invoke方法传进来的,往上追溯M.invoke方法是在P.invoke方法中被调用的,在P.invoke方法中将自己的参数args传给M.invoke。还记得P.invoke方法的作用吗?当外部调用Api中的方法时,拦截Api中的方法,获取所调用方法的信息,所以这个args就是外部调用Api中方法时所传入的参数的值。
知道了args是什么,然后来看其他三个参数。另三个参数是HttpServiceMethod中声明的成员变量,这三个变量是在它的构造方法中进行赋值的(构造方法中也只有给这三个成员变量赋值的代码),值就是通过构造方法传入进来的,所以这三个成员变量值的来源可以从创建对象处找到。因此来看CallAdapted对象的创建代码(前面说到了HttpServiceMethod是抽象类,CallAdapted是其子类),是在HttpServiceMethod.parseAnnotations方法中:
abstract class HttpServiceMethod<ResponseT, ReturnT> extends ServiceMethod<ReturnT> {
static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(Retrofit retrofit, Method method, RequestFactory requestFactory) {
...
CallAdapter<ResponseT, ReturnT> callAdapter = createCallAdapter(retrofit, method, adapterType, annotations);
Converter<ResponseBody, ResponseT> responseConverter = createResponseConverter(retrofit, method, responseType);
okhttp3.Call.Factory callFactory = retrofit.callFactory;
if (!isKotlinSuspendFunction) {
return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
} else ...
}
其中
-
requestFactory是直接取的HttpServiceMethod.parseAnnotations方法的参数,其是在其父类ServiceMethod的parseAnnotations方法中创建的:abstract class ServiceMethod { static ServiceMethod parseAnnotations(Retrofit retrofit, Method method) { // ① RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method); ... return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory); }
-
responseConverter是由createResponseConverter方法返回的,createResponseConverter方法里就是获取了Retrofit中的Converter实例,Converter是一个接口,和上面的CallAdapter类似,内部也创建了一个Factory抽象类,通过Factory里的responseBodyConverter方法来返回Converter的实例。Converter最常用的一个实现类是GsonResponseBodyConverter,看着是不是很眼熟,没错,它就是由GsonConverterFactory(Converter.Factory的一个实现类)中的responseBodyConverter方法返回的,GsonConverterFactory就是我们经常在开头实例化Retrofit时通过addConverterFactory(xxx)方法传入的,用来将服务器返回的网络请求结果转换成我们创建的Bean类。 -
callFactory也是获取的Retrofit中的callFactory,它的类型是okhttp3.Call.Factory,是一个接口,它的实现类就是在开头实例化Retrofit时通过callFactory(xxx)方法传入的,如果没有调用该方法传入实现类,则使用okhttp中的默认实现类OkHttpClient。
我们这里先打断一下,先来看下RequestFactory的作用。
重点四:RequestFactory
还记得我们上面说过的记住①处的RequestFactory吗,它就是在这里用到的,通过RequestFactory.parseAnnotations方法实例化后,最终它会被传入到OkHttpCall中。来看下RequestFactory是做什么的,点进parseAnnotations方法:
final class RequestFactory {
static RequestFactory parseAnnotations(Retrofit retrofit, Method method) {
return new Builder(retrofit, method).build();
}
...
}
很简单,只是new了一个Builder对象并调用了其build方法,Builder是RequestFactory类里的内部类,作用显然就是创建RequestFactory对象了。先看下Builder的构造方法:
static final class Builder {
...
final Retrofit retrofit;
final Method method;
final Annotation[] methodAnnotations;
final Annotation[][] parameterAnnotationsArray;
final Type[] parameterTypes;
...
Builder(Retrofit retrofit, Method method) {
this.retrofit = retrofit;
this.method = method;
this.methodAnnotations = method.getAnnotations();
this.parameterTypes = method.getGenericParameterTypes();
this.parameterAnnotationsArray = method.getParameterAnnotations();
}
构造方法接收了retrofit和method,retrofit不用说,method就是上面P.invoke方法中传入进来的,也就是Api中的方法实例。可以看到构造方法中调用了method的三个方法,分别是获取method的注解、获取method的参数类型、获取method的参数的注解。看到注解有没有联想到什么?我们在创建Api以及里面的方法时,是不是要使用很多注解?那是不是可以猜到点什么?继续来看Builder的build方法:
static final class Builder {
...
RequestFactory build() {
for (Annotation annotation : methodAnnotations) {
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);
}
}
可以看到,build方法里首先对methodAnnotations调用了parseMethodAnnotation方法,根据方法名很容易猜到该方法是解析method的注解,点击去看一下:
private void parseMethodAnnotation(Annotation annotation) {
if (annotation instanceof DELETE) {
parseHttpMethodAndPath("DELETE", ((DELETE) annotation).value(), false);
} else if (annotation instanceof GET) {
parseHttpMethodAndPath("GET", ((GET) annotation).value(), false);
} else if (annotation instanceof HEAD) {
parseHttpMethodAndPath("HEAD", ((HEAD) annotation).value(), false);
} else if (annotation instanceof PATCH) {
parseHttpMethodAndPath("PATCH", ((PATCH) annotation).value(), true);
} else if (annotation instanceof POST) {
parseHttpMethodAndPath("POST", ((POST) annotation).value(), true);
} else if (annotation instanceof PUT) {
parseHttpMethodAndPath("PUT", ((PUT) annotation).value(), true);
} else if (annotation instanceof OPTIONS) {
parseHttpMethodAndPath("OPTIONS", ((OPTIONS) annotation).value(), false);
} else ...
}
果然没错,正是我们在Api中的方法上使用的注解,在这里拿到注解并进行解析。
后面也就很明了了,解析完method的注解后,后续就使用parseParameter方法解析method的参数,在parseParameter方法中会调用parseParameterAnnotation方法解析method的参数的注解。解析完毕得到method的各项数据后,new一个RequestFactory对象将Builder传入。最后再来看下RequestFactory的构造方法:
RequestFactory(Builder builder) {
method = builder.method;
baseUrl = builder.retrofit.baseUrl;
httpMethod = builder.httpMethod;
relativeUrl = builder.relativeUrl;
headers = builder.headers;
contentType = builder.contentType;
hasBody = builder.hasBody;
isFormEncoded = builder.isFormEncoded;
isMultipart = builder.isMultipart;
parameterHandlers = builder.parameterHandlers;
isKotlinSuspendFunction = builder.isKotlinSuspendFunction;
}
这里将retrofit中的baseUrl数据以及builder中解析的method的各项数据赋值给RequestFactory中的成员变量保存下来,等待后续使用。
经过以上分析,我们知道了RequestFactory的作用是对Method进行解析,拿到Method的配置数据(Method就是我们在Api中创建的方法,每个方法就是一个网络请求,每个请求都会根据实际需求使用注解进行配置)并保存到自身中,然后将自身传入到OkHttpCall中。可以说RequestFactory就是网络请求配置数据的载体。
重点三:OkHttpCall(二)
现在再来回过头看OkHttpCall,我们弄清了创建OkHttpCall对象时传入的四个参数都是什么,接下来就要看OkHttpCall中做了什么。上面说到OkHttpCall是Call的实现类,而我们拿到Call以后主要是调用enqueue方法进行网络请求,所以主要看OkHttpCall中是如何实现enqueue的:
final class OkHttpCall<T> implements Call<T> {
...
@Override
public void enqueue(final Callback<T> callback) {
Objects.requireNonNull(callback, "callback == null");
okhttp3.Call call;
Throwable failure;
...
if (call == null && failure == null) {
try {
// ①创建call对象
call = rawCall = createRawCall();
} catch (Throwable t) {
throwIfFatal(t);
failure = creationFailure = t;
}
}
}
if (failure != null) {
callback.onFailure(this, failure);
return;
}
...
// ②进行网络请求
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) {
callFailure(e);
return;
}
try {
callback.onResponse(OkHttpCall.this, response);
} catch (Throwable t) {
}
}
@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) {
}
}
});
}
主要看关键代码,enqueue方法中声明了okhttp3.Call类型的变量call,在①处通过createRawCall方法进行实例化,点进createRawCall方法:
private okhttp3.Call createRawCall() throws IOException {
okhttp3.Call call = callFactory.newCall(requestFactory.create(args));
if (call == null) {
throw new NullPointerException("Call.Factory returned null.");
}
return call;
}
发现里面是调用了callFactory.newCall(requestFactory.create(args)方法,callFactory上面我们分析过了,是OkHttpCall构造方法其中的一个参数,这里我们就用它的默认实现类OkHttpClient来看。看一下OkHttpClient中的newCall方法:
public class OkHttpClient implements Cloneable, Call.Factory, WebSocket.Factory {
...
@Override public Call newCall(Request request) {
return RealCall.newRealCall(this, request, false /* for web socket */);
}
}
该方法接收一个Request类型的参数,该参数是通过requestFactory.create(args)创建的,上面我们分析了RequestFactory的作用是解析并保存网络请求的配置信息等待后续使用,就是在这里使用的,看一下create方法:
okhttp3.Request create(Object[] args) throws IOException {
...
int argumentCount = args.length;
...
RequestBuilder requestBuilder = new RequestBuilder(httpMethod,baseUrl,relativeUrl,headers,contentType,hasBody,isFormEncoded,isMultipart);
...
List<Object> argumentList = new ArrayList<>(argumentCount);
for (int p = 0; p < argumentCount; p++) {
argumentList.add(args[p]);
handlers[p].apply(requestBuilder, args[p]);
}
return requestBuilder.get().tag(Invocation.class, new Invocation(method, argumentList)).build();
}
可以看到在create方法中,根据Method的注解信息、参数类型信息、参数的注解信息以及参数值数据,生成一个okhttp3.Request实例并返回,这个okhttp3.Request就是最终完整的网络请求体了。
将okhttp3.Request实例传入到上面的newCall方法中,newCall方法里调用了RealCall.newRealCall方法得到RealCall对象并返回,RealCall是okhttp3.Call的实现类。
现在回到OkHttpCall中的enqueue方法,enqueue方法里的变量call现在已经确定了,是一个RealCall实例,后面就是②处调用call的enqueue方法执行网络请求。至此整个Retrofit流程的源码分析完毕,我们也彻底明白了为什么说Retrofit底层是使用okhttp进行网络请求的。
总结
最后再来总结一下Retrofit的完整流程(retrofit和okhttp中存在同名接口Call,下面称retrofit中的Call为R.Call,okhttp中的Call为ok.Call):
首先创建Retrofit实例retrofit,可根据需要传入①CallFactory ②ConverterFactory等,然后调用retrofit的create方法,获取到Api的动态代理类,每当Api中的方法被调用时,代理类会拦截Api的方法,将其转换成Method对象传入自身的P.invoke方法中,在P.invoke方法中调用ServiceMethod.parseAnnotations(retrofit, method)方法将Method包装成ServiceMethod,并调用其M.invoke方法,M.invoke方法中会创建并返回OkHttpCall对象,OkHttpCall是R.Call(也就是创建Api中的方法时所定义的返回值Call)的实现类。通过M.invoke方法拿到Call对象后,再调用Call的enqueue方法即可进行网络请求。
ServiceMethod中声明了一个RequestFactory类型的变量requestFactory,在parseAnnotations方法中会实例化requestFactory。RequestFactory是Method数据的载体类,里面存储的是Method的方法注解、参数类型、参数的注解等数据,这些数据会在RequestFactory实例化时解析Method对象来得到。在M.invoke方法中创建OkHttpCall的对象时,会将自身(即HttpServiceMethod)中存储的requestFactory callFactory responseConverter以及M.invoke方法的参数args传入到OkHttpCall中。其中callFactory是上面①的实例,responseConverter是上面②的实例,args是Method对象的参数的值。
当调用R.call的enqueue时,实际执行的是OkHttpCall中的enqueue方法,在该方法中声明了ok.Call类型的变量call,通过callFactory.newCall(requestFactory.create(args))方法获取到RealCall对象,RealCall是ok.Call的实现类,获取到RealCall对象后调用其enqueue方法来执行网络请求操作。所以当我们在外部调用R.Call的enqueue方法时,最终实际执行网络请求操作的是ok.Call的enqueue方法。
callFactory.newCall方法接收的是okhttp3.Request类型的参数,这个Request参数就是最终的网络请求体,它是在RequestFactory中的create方法里创建的,RequestFactory在create方法中将Method的方法注解、参数类型、参数的注解和参数的值等数据转化成一个okhttp3.Request对象并返回。
好了流程总结完毕,现在来思考一下上面提过的为什么Retrofit中要缓存ServuceMothod。ServiceMothod是什么? 它是由Method经过包装而来的,Method就是Api中的方法,而Api中的方法就是一个个的网络请求,所以ServiceMothod可以理解为是网络请求的承载体,而一个网络请求可能会被多次发起,所以将ServiceMothod缓存起来,后面再次发起该网络请求时可以立即执行,无需重新创建对象,从而提升性能。