Retrofit源码分析
文章目录
前言
本文基于retrofit 2.9.0,在2.6.0版本之后,retrofit对kotlin协程进行了支持,主要是加入了一些kotlin的扩展函数。
如有谬误,还请各位大佬指正。
概述
Retrofit并不是一个网络请求库,它的作用主要是为了简化网络请求的构建和对返回数据的处理。它的网络请求是通过square自家的OkHttp实现的。
主要优点:
- 可以在构建retrofit时添加多种类型的转换器,让我们不用再手动解析返回的数据了
- 将接口的定义与使用分离开来,实现解耦
- 可以和kotlin协程、RxJava等配合使用简化回调,优雅地实现网络请求
- 请求速度快,使用OkHttp实现进行请求
简单使用
1.首先创建一个请求接口:
interface PlaceService {
@GET("v2/place?lang=zh_CN")
fun searchPlaces(@Query("query") query: String): Call<PlaceModel>
}
2.再通过如下代码通过OkHttp发起网络请求
//构建Retrofit对象
val retrofit = Retrofit.Builder()
.baseUrl(url)
.addConverterFactory(GsonConverterFactory.create())
.build()
//创建接口实例
val placeService = retrofit.create(PlaceService::class.java)
//通过接口实例调用请求方法获取Call对象
val call = placeService.searchPlaces("xxx")
//通过Call的enqueue或execute方法进行异步或同步请求
call.enqueue(object : Callback<PlaceModel> {
override fun onFailure(call: Call<PlaceModel>, t: Throwable) {
...
}
override fun onResponse(call: Call<PlaceModel>, response: Response<PlaceModel>) {
...
}
})
需要注意的是:retrofit的请求URL是由构建retrofit对象时baseUrl中的参数和@GET注解中的Url拼接而来的。
更多Retrofit的使用在我另一篇博客:Retrofit的简单使用
源码分析
1.Retrofit的创建
Retrofit.Builder()
public Builder() {
this(Platform.get());
}
Platform.get()
这个方法根据不同的平台返回不同的线程池,在Android平台会创建MainThreadExecutor,它会通过handler将Runnable回调到主线程执行:
class Platform {
private static final Platform PLATFORM = findPlatform();
static Platform get() {
return PLATFORM;
}
private static Platform findPlatform() {
return "Dalvik".equals(System.getProperty("java.vm.name"))
? new Android() //
: new Platform(true);
}
static final class Android extends Platform {
Android() {
super(Build.VERSION.SDK_INT >= 24);
}
@Override
public Executor defaultCallbackExecutor() { //默认回调线程池为MainThreadExecutor
return new MainThreadExecutor();
}
@Nullable
@Override
Object invokeDefaultMethod(
Method method, Class<?> declaringClass, Object object, Object... args) throws Throwable {
if (Build.VERSION.SDK_INT < 26) {
throw new UnsupportedOperationException(
"Calling default methods on API 24 and 25 is not supported");
}
return super.invokeDefaultMethod(method, declaringClass, object, args);
}
static final class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper()); //创建主线程的handler
@Override
public void execute(Runnable r) {
handler.post(r); //通过handler将Runnable发送至主线程
}
}
}
}
Retrofit.Builder.build()
这个Builder是Retrofit的内部类,主要用于构建Retrofit对象。它的这个build方法就是用于创建Retrofit实例。
public Retrofit build() {
if (baseUrl == null) { //baseUrl为null,直接抛出异常
throw new IllegalStateException("Base URL required.");
}
//callFactory由Builder的callFactory方法设置,如果需要对OkHttpClient进行配置,
//就可以构建OkHttpClient对象,设置给callFactory并通过callFactory方法传入即可
okhttp3.Call.Factory callFactory = this.callFactory;
//否则直接创建OkHttpClient对象
if (callFactory == null) {
callFactory = new OkHttpClient();
}
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
//获取对应平台的defaultCallbackExecutor,安卓平台会直接创建MainThreadExecutor,上面代码提到过
callbackExecutor = platform.defaultCallbackExecutor();
}
//主要用于存储对Call进行转化的对象
List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));
//转换器列表,构建Retrofit对象时通过addConvertFactory可以添加转换器
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());
//将上面的属性传入,创建Retrofit对象
return new Retrofit(
callFactory,
baseUrl,
unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories),
callbackExecutor,
validateEagerly);
}
2.Call对象的创建
上面简单使用中通过retrofit的create方法来创建了接口的动态代理对象
val placeService = retrofit.create(PlaceService::class.java)
再通过这个动态代理对象调用接口中的方法就创建了Call对象。
val call = placeService.searchPlaces("xxx")
Retrofit.create(final Class service)
public <T> T create(final Class<T> service) {
validateServiceInterface(service);
//下面直接返回了一个动态代理对象
return (T)
Proxy.newProxyInstance(
service.getClassLoader(),
new Class<?>[] {service},
//当我们通过动态代理对象调用接口中的方法时,最终会调用下面接口中的invoke方法
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的方法,如toString等,就进行正常调用
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
args = args != null ? args : emptyArgs;
//default method指的就是接口中定义的非抽象非静态有方法体的方法
//我们一般不会中接口中这样声明方法,因此默认调用下面的loadServiceMethod(method).invoke(args)
return platform.isDefaultMethod(method)
? platform.invokeDefaultMethod(method, service, proxy, args)
: loadServiceMethod(method).invoke(args);
}
});
}
Retrofit.loadServiceMethod(Method method)
ServiceMethod<?> loadServiceMethod(Method method) {
//先从缓存中获取
ServiceMethod<?> result = serviceMethodCache.get(method);
if (result != null) return result;
//没有缓存就通过ServiceMethod.parseAnnotations(this, method)创建,并将其加入缓存
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
result = ServiceMethod.parseAnnotations(this, method);
serviceMethodCache.put(method, result);
}
}
return result;
}
//ServiceMethod.java
abstract class ServiceMethod<T> {
static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
//创建RequestFactory对象
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.");
}
//通过接口中的注解来构建一个可以重用的ServiceMethod对象
return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
}
abstract @Nullable T invoke(Object[] args);
}
上面通过RequestFactory.parseAnnotations(retrofit, method)方法构建RequestFactory对象:
static RequestFactory parseAnnotations(Retrofit retrofit, Method method) {
return new Builder(retrofit, method).build();
}
//Builder是RequestFactory的内部类
Builder(Retrofit retrofit, Method method) {
this.retrofit = retrofit;
this.method = method;
this.methodAnnotations = method.getAnnotations();
this.parameterTypes = method.getGenericParameterTypes();
this.parameterAnnotationsArray = method.getParameterAnnotations();
}
RequestFactory build() {
//遍历解析接口中所有请求方法上的注解和其中的参数,如@GET、@POST等
for (Annotation annotation : methodAnnotations) {
parseMethodAnnotation(annotation);
}
if (httpMethod == null) {
throw methodError(method, "HTTP method annotation is required (e.g., @GET, @POST, etc.).");
}
if (!hasBody) {
if (isMultipart) {
throw methodError(
method,
"Multipart can only be specified on HTTP methods with request body (e.g., @POST).");
}
if (isFormEncoded) {
throw methodError(
method,
"FormUrlEncoded can only be specified on HTTP methods with "
+ "request body (e.g., @POST).");
}
}
//下面解析接口中请求方法中参数的注解,如@Query、@Part等
int parameterCount = parameterAnnotationsArray.length;
parameterHandlers = new ParameterHandler<?>[parameterCount];
for (int p = 0, lastParameter = parameterCount - 1; p < parameterCount; p++) {
//通过parseParameter解析请求方法中的参数和注解,下面还会说道
parameterHandlers[p] =
parseParameter(p, parameterTypes[p], parameterAnnotationsArray[p], p == lastParameter);
}
if (relativeUrl == null && !gotUrl) {
throw methodError(method, "Missing either @%s URL or @Url parameter.", httpMethod);
}
if (!isFormEncoded && !isMultipart && !hasBody && gotBody) {
throw methodError(method, "Non-body HTTP method cannot contain @Body.");
}
if (isFormEncoded && !gotField) {
throw methodError(method, "Form-encoded method must contain at least one @Field.");
}
if (isMultipart && !gotPart) {
throw methodError(method, "Multipart method must contain at least one @Part.");
}
//传入Builder对象创建RequestFactory对象
return new RequestFactory(this);
}
//上面的parseParameter方法
private @Nullable ParameterHandler<?> parseParameter(
int p, Type parameterType, @Nullable Annotation[] annotations, boolean allowContinuation) {
...
if (result == null) {
if (allowContinuation) {
try {
//下面通过传入的请求方法的参数的类是否是Continuation.class来判断请求方法是否是kotlin的挂起函数。通过反编译kotlin的挂起函数的字节码我们可以发现它为我们自动添加了一个Continuation对象,因此可以用来判断是否是kotlin挂起函数
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(…)
这个方法在上面loadServiceMethod方法中用于创建一个ServiceMethod对象,HttpServiceMethod是ServiceMethod的子类。
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;
//下面代码主要是获取请求方法的返回类型,kotlin的挂起函数和普通函数获取方式有所不同
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);
continuationWantsResponse = true;
} else {
}
adapterType = new Utils.ParameterizedTypeImpl(null, Call.class, responseType);
annotations = SkipCallbackExecutorImpl.ensurePresent(annotations);
} else {
adapterType = method.getGenericReturnType();
}
//调用createCallAdapter来获取CallAdapter对象
CallAdapter<ResponseT, ReturnT> callAdapter =
createCallAdapter(retrofit, method, adapterType, annotations);
Type responseType = callAdapter.responseType();
//...省略一些检查responseType的代码
//遍历addConvertFactory方法中添加的转换器,并返回一个相应的转换器用来转换返回的数据
Converter<ResponseBody, ResponseT> responseConverter =
createResponseConverter(retrofit, method, responseType);
okhttp3.Call.Factory callFactory = retrofit.callFactory;
//1.默认情况,不是kotlin挂起函数,直接返回CallAdapted对象
if (!isKotlinSuspendFunction) {
return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
}
//下面两种是kotlin挂起函数的情况
else if (continuationWantsResponse) {
//2.返回值想要完整的Response
return (HttpServiceMethod<ResponseT, ReturnT>)
new SuspendForResponse<>(
requestFactory,
callFactory,
responseConverter,
(CallAdapter<ResponseT, Call<ResponseT>>) callAdapter);
} else {
//3.只需要响应体
return (HttpServiceMethod<ResponseT, ReturnT>)
new SuspendForBody<>(
requestFactory,
callFactory,
responseConverter,
(CallAdapter<ResponseT, Call<ResponseT>>) callAdapter,
continuationBodyNullable);
}
}
上面createCallAdapter方法会通过调用callAdapterFactories添加对象的get方法来获取CallAdapter对象。在Retrofit内部类Builder的build方法中会默认添加DefaultCallAdapterFactory对象,它的get方法如下:
@Override
public @Nullable CallAdapter<?, ?> get(
Type returnType, Annotation[] annotations, Retrofit retrofit) {
if (getRawType(returnType) != Call.class) {
return null;
}
if (!(returnType instanceof ParameterizedType)) {
throw new IllegalArgumentException(
"Call return type must be parameterized as Call<Foo> or Call<? extends Foo>");
}
final Type responseType = Utils.getParameterUpperBound(0, (ParameterizedType) returnType);
final Executor executor =
Utils.isAnnotationPresent(annotations, SkipCallbackExecutor.class)
? null
: callbackExecutor;
//创建一个CallAdapter对象
return new CallAdapter<Object, Call<?>>() {
@Override
public Type responseType() {//接口中请求方法返回值的真实类型,也就是返回的Call对象泛型中的类型
return responseType;
}
@Override
public Call<Object> adapt(Call<Object> call) {
//创建ExecutorCallbackCall对象
return executor == null ? call : new ExecutorCallbackCall<>(executor, call);
}
};
}
ExecutorCallbackCall是线程池和Call对象的封装类,这里的executor其实就是上面Platform类中创建的MainThreadExecutor,当调用ExecutorCallbackCall的enqueue方法时,其中会调用Call对象的enqueue方法通过OkHttp发起网络请求。数据返回后通过这个MainThreadExecutor将数据回调回主线程。
ServiceMethod.invoke(Object[] args)
这个方法在Retrofit.create方法中:loadServiceMethod(method).invoke(args),它的实现在HttpServiceMethod中。
@Override
final @Nullable ReturnT invoke(Object[] args) {
Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
return adapt(call, args);
}
可以看到,它主要完成了两件事:
- 通过多态创建Call对象
- 调用adapt抽象方法
这个adapt方法的实现就在HttpServiceMethod的三个静态内部类CallAdapted、SuspendForResponse、SuspendForBody中
2.1 默认情况
即HttpServiceMethod.parseAnnotations(…)方法返回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);
}
}
//DefaultCallAdapterFactory的adapt方法,上面提到过:
@Override
public Call<Object> adapt(Call<Object> call) {
//前面已经创建过ExecutorCallbackCall对象,这里直接返回Call对象
return executor == null ? call : new ExecutorCallbackCall<>(executor, call);
}
当我们通过接口的动态代理调用请求方法拿到这里返回的Call对象后,一般会调用它的enqueue方法来进行异步请求,它会调用OkHttpCall的enqueue方法,其中会调用Call的enqueue方法:
//OkHttpCall.enqueue(final Callback<T> callback)方法中
//最终调用了RealCall的enqueue方法来进行请求,这就到了OkHttp的内容了
call.enqueue(
new okhttp3.Callback() {
@Override
public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
Response<T> response;
try {
//通过parseResponse方法解析返回的数据
response = parseResponse(rawResponse);
} catch (Throwable e) {
throwIfFatal(e);
callFailure(e);
return;
}
try {
//通过回调调用DefaultCallAdapterFactory中enqueue方法回调接口的onResponse实现,它会通过MainThreadExecutor将解析后的数据回调到主线程
//也就是说,我们在使用call.enqueue(...)时其中的onResponse和onFailure方法在主线程执行
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
}
}
});
OkHttpCall.parseResponse(okhttp3.Response rawResponse)
Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
ResponseBody rawBody = rawResponse.body();
// Remove the body's source (the only stateful object) so we can pass the response along.
rawResponse =
rawResponse
.newBuilder()
.body(new NoContentResponseBody(rawBody.contentType(), rawBody.contentLength()))
.build();
int code = rawResponse.code();
if (code < 200 || code >= 300) { //状态码不是2XX,请求不成功
try {
// Buffer the entire body to avoid future I/O.
ResponseBody bufferedBody = Utils.buffer(rawBody);
return Response.error(bufferedBody, rawResponse);
} finally {
rawBody.close();
}
}
if (code == 204 || code == 205) { //请求成功,但是返回内容为空
rawBody.close();
return Response.success(null, rawResponse);
}
ExceptionCatchingResponseBody catchingBody = new ExceptionCatchingResponseBody(rawBody);
try {
//调用Converter对象的convert方法来转换数据,这就是HttpServiceMethod的parseAnnotations方法中创建的转换器
T body = responseConverter.convert(catchingBody);
return Response.success(body, rawResponse);
} catch (RuntimeException e) {
...
}
}
Converter是一个接口,它有很多实现类。如果我们在构建Retrofit对象时加入了GsonConverterFactory,其中会创建GsonResponseBodyConverter对象。
GsonResponseBodyConverter的convert方法:
@Override
public T convert(ResponseBody value) throws IOException {
JsonReader jsonReader = gson.newJsonReader(value.charStream());
try {
//转换并返回转换后的数据
T result = adapter.read(jsonReader);
if (jsonReader.peek() != JsonToken.END_DOCUMENT) {
throw new JsonIOException("JSON document was not fully consumed.");
}
return result;
} finally {
value.close();
}
}
2.2 kotlin挂起函数只需要响应体的情况
即HttpServiceMethod.parseAnnotations(…)方法返回SuspendForBody对象。SuspendForBody是HttpServiceMethod的静态内部类。
static final class SuspendForBody<ResponseT> extends HttpServiceMethod<ResponseT, Object> {
private final CallAdapter<ResponseT, Call<ResponseT>> callAdapter;
private final boolean isNullable;
SuspendForBody(
RequestFactory requestFactory,
okhttp3.Call.Factory callFactory,
Converter<ResponseBody, ResponseT> responseConverter,
CallAdapter<ResponseT, Call<ResponseT>> callAdapter,
boolean isNullable) {
super(requestFactory, callFactory, responseConverter);
this.callAdapter = callAdapter;
this.isNullable = isNullable;
}
@Override
protected Object adapt(Call<ResponseT> call, Object[] args) {
call = callAdapter.adapt(call);
Continuation<ResponseT> continuation = (Continuation<ResponseT>) args[args.length - 1];
try {
//根据泛型和返回值类型是否可空调用相应的方法,默认不可空,调用await方法
return isNullable
? KotlinExtensions.awaitNullable(call, continuation)
: KotlinExtensions.await(call, continuation);
} catch (Exception e) {
return KotlinExtensions.suspendAndThrow(e, continuation);
}
}
}
KotlinExtensions.await(call, continuation)
为什么下面Call的扩展函数没有参数,而上面java调用Kotlin的扩展函数时传入了两个参数了呢?
因为下面Call的await扩展函数实际上被编译为文件中和文件同名的类KotlinExtensions中的静态方法,因为Call的扩展函数中有Call对象的上下文,因此需要将Call对象作为第一个参数传入才能调用它的方法;
又因为下面kotlin扩展函数同时是一个挂起函数,所以又需要传入一个continuation对象
//KotlinExtensions.kt
suspend fun <T : Any> Call<T>.await(): T {
return suspendCancellableCoroutine { continuation ->
continuation.invokeOnCancellation {suspend fun <T : Any> Call<T>.await(): T {
return suspendCancellableCoroutine { continuation ->
continuation.invokeOnCancellation {
cancel()
}
//调用Call的enqueue方法请求数据
enqueue(object : Callback<T> {
override fun onResponse(call: Call<T>, response: Response<T>) {
if (response.isSuccessful) { //响应码为2xx,请求和相应正常
val body = response.body() //获取相应体
if (body == null) {
val invocation = call.request().tag(Invocation::class.java)!!
val method = invocation.method()
val e = KotlinNullPointerException("Response from " +
method.declaringClass.name +
'.' +
method.name +
" was null but response body type was declared as non-null")
continuation.resumeWithException(e) //响应体为空,调用resumeWithException方法恢复协程并抛出一个异常
} else {
continuation.resume(body) //正常恢复协程
}
} else {
continuation.resumeWithException(HttpException(response)) //请求或相应异常
}
}
override fun onFailure(call: Call<T>, t: Throwable) {
continuation.resumeWithException(t) //请求失败,可能因为网络等问题
}
})
}
}
2.3 kotlin挂起函数返回值想要完整的Response的情况
和上面SuspendForBody很类似,只是SuspendForResponse的adapt方法会调用Call的awaitResponse扩展函数。它和await方法的区别仅在于onResponse方法中不会获取获取请求体,而是直接返回Response对象,这里不再赘述。
有了上面Retrofit对kotlin的支持,我们就可以这样优雅地实现网络请求,而不用再自己实现一个Call的await扩展函数了:
fun searchPlace() = withContext(Dispatchers.IO) {
val retrofit = Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl("xxx")
.build()
retrofit.create(PlaceService::class.java).searchPlaces("xxx")
}
上面创建retrofit的过程还可以进一步进行封装,这样就可以实现一行代码来进行网络请求了,具体实现就交给读者盆友们来完成了。
小结
Retrofit的简单使用和上面源码分析结合起来小结一哈:
- 首先通过Retrofit的内部类Builder的build方法构建Retrofit对象
- 再通过retrofit的create方法创建了请求接口的动态代理对象,这个动态代理对象的第三个参数是InvocationHandler接口的实例,当通过这个动态代理对象调用请求方法时就会回调这个接口的invoke方法。其中最重要的就是loadServiceMethod(method).invoke(args); 这行代码。
- 这个loadServiceMethod方法中会先从缓存中获取ServiceMethod,没有的话再去创建一个HttpServiceMethod对象并将其存入缓存。它会对请求方法上面的请求方法注解、参数类型、返回值类型等进行解析,并判断该方法是否是kotlin挂起函数,根据请求方法返回HttpServiceMethod中不同的实现类对象。
- invoke方法会调用ServiceMethod三个最终实现类的adapt方法。
- 对于kotlin的挂起函数,调用adapt方法会直接调用Call对象相应的扩展函数,扩展函数内部会直接调用它的enqueue方法发起异步请求;
- 对于普通的请求方法,invoke方法会创建一个ExecutorCallbackCall对象将OkHttpCall对象和MainThreadExecutor封装到其中,在我们显示调用Call的enqueue方法时会调用到ExecutorCallbackCall的enqueue方法,它通过调用OkHttpCall的enqueue方法发起网络请求,在回调中会在构建Retrofit对象时添加的Converter中寻找相应的转换器对返回的数据进行转换。而在ExecutorCallbackCall的enqueue方法中会通过MainThreadExecutor将数据回调到主线程。
参考资料
《Android进阶之光》