带你一步步剖析Retrofit-源码解析:一款基于-OkHttp-实现的网络请求框架

}
GitHubService service = retrofit.create(GitHubService.class);

之后,我们调用 service 中对应的方法,就可以获取到 Call 对象了。

通过对 Call 对象调用 enqueue 就可以实现对请求的异步调用,而通过 execute 方法则可以实现请求的同步调用。

Retrofit 对象的构建

Retrofit 采用了 Builder 模式进行了构建,在 Builder 中可以进行非常多的配置,其中可以对 baseUrlokhttpClientconverterFactorycallAdapterFactory 等进行设置。

这里没什么特别的,都是一些简单的赋值,就不再关注了,我们只需要看看最后 Retrofit 被传入了哪些参数。它最后调用了下面这个构造函数对参数进行了初始化。

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;
}

Service 对象的创建
动态代理创建 Service 代理类

接着我们看到自己定义的 interface 是如何仅仅靠传递 classRetrofit.create 就能实现实例的获取的,它明明只是个接口呀?

public T create(final Class service) {
// 对 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);
}
// 如果是对应平台本身的类就有的方法,照常调用
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
// 否则通过 loadServiceMethod 方法获取到对应 Method 并 invoke
return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
}
});
}

可以看到,实际上 Service 对象的获取是通过动态代理实现的。这里首先通过 validateServiceInterface 方法对接口进行了检测,之后通过动态代理对该接口进行了代理。

对于 Object 类本身独有以及对应平台本身就存在的方法,就照常调用,否则通过 loadServiceMethodService 中对应的 Method 对象进行处理,之后对其调用 invoke 方法。

这里说明了 Retrofit 不是在创建 Service 接口对应对象时就立即对所有该接口中的所有方法都进行注解的解析,而是采用了在方法被调用时才进行注解的解析这种懒加载的思想。

接着我们看看 validateServiceInterface 方法:

private void validateServiceInterface(Class<?> service) { // 判断是否是接口 if (!service.isInterface()) { throw new IllegalArgumentException("API declarations must be interfaces."); } // 判断该接口及其继承的所有接口是否包含了范型参数,如果包含则抛出异常 Deque

首先,这个方法对 service 进行了检测,保证了它是一个接口并且它和它继承的类中没有范型参数。

之后如果在 Retrofit 创建时设置 validateEagerly 为 true 的话,会对 Service 中所有非平台独有且非static的方法通过 loadServiceMethod 方法提前进行处理

Service 中方法的解析
那么我们来看看 loadServiceMethod 究竟做了些什么:

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;
}

首先它会采用 Double Check 的方式尝试从 serviceMethodCache 缓存中获取 ServiceMethod 对象,如果获取不到则通过 ServiceMethod.parseAnnotations 方法对该 Method 的注解进行处理并将得到的 ServiceMethod 对象加入了缓存。

也就是说为了避免多次对方法的注解进行处理,Retrofit 采用了一个 serviceMethodCache 对解析后的 ServiceMethod 进行缓存。

接着我们就来看看,parseAnnotations 方法是如何对方法的注解进行解析的。

static ServiceMethod 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);
}

这里先通过 RequestFactory.parseAnnotations 方法对注解解析并获得了一个 RequestFactory 对象。

之后又通过 HttpServiceMethod.parseAnnotations 方法传入了 requestFactory 继续进行注解的解析并获得 ServiceMethod 对象

注解解析

我们先看看 RequestFactory.parseAnnotations

static RequestFactory parseAnnotations(Retrofit retrofit, Method method) {
return new Builder(retrofit, method).build();
}

它把 Method 传入 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();
}

Builder 中通过反射获取到method所包含的注解、参数包含的范型以及参数的注解。

接着看看 build 方法:

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 方法中主要是对方法的每个注解调用了 parseMethodAnnotation 进行了解析,并且对每个参数调用了 parseParamter 方法解析为了 ParamterHandler 对象。

parseMethodAnnotation 的代码如下:

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 if (annotation instanceof HTTP) {
HTTP http = (HTTP) annotation;
parseHttpMethodAndPath(http.method(), http.path(), http.hasBody());
} else if (annotation instanceof retrofit2.http.Headers) {
String[] headersToParse = ((retrofit2.http.Headers) annotation).value();
if (headersToParse.length == 0) {
throw methodError(method, “@Headers annotation is empty.”);
}
headers = parseHeaders(headersToParse);
} else if (annotation instanceof Multipart) {
if (isFormEncoded) {
throw methodError(method, “Only one encoding annotation is allowed.”);
}
isMultipart = true;
} else if (annotation instanceof FormUrlEncoded) {
if (isMultipart) {
throw methodError(method, “Only one encoding annotation is allowed.”);
}
isFormEncoded = true;
}
}

这里实际上就是对每一种 HTTP 所支持的类型进行了支持,获取到了对应注解的中的 url,并调用parseHttpMethodAndPath 进行处理,同时对 Headers 注解则是通过 parseHeaders 进行了处理。

对 Http 请求方式和 Path 的处理

对于 Method 和 Path,通过 parseHttpMethodAndPath 进行了参数的赋值:

private void parseHttpMethodAndPath(String httpMethod, String value, boolean hasBody) {
if (this.httpMethod != null) {
throw methodError(method, “Only one HTTP method is allowed. Found: %s and %s.”,
this.httpMethod, httpMethod);
}
this.httpMethod = httpMethod;
this.hasBody = hasBody;
if (value.isEmpty()) {
return;
}
// Get the relative URL path and existing query string, if present.
int question = value.indexOf(‘?’);
if (question != -1 && question < value.length() - 1) {
// Ensure the query string does not have any named parameters.
String queryParams = value.substring(question + 1);
Matcher queryParamMatcher = PARAM_URL_REGEX.matcher(queryParams);
if (queryParamMatcher.find()) {
throw methodError(method, "URL query string “%s” must not have replace block. "+ “For dynamic query parameters use @Query.”, queryParams);
}
}
this.relativeUrl = value;
this.relativeUrlParamNames = parsePathParameters(value);
}

这里实际上就是对不同 HTTP 请求方式和 Path 进行了赋值,同时通过正则表达式保证了这个接口的 Path 中没有包含参数。

对 Headers 的处理

private Headers parseHeaders(String[] headers) {
Headers.Builder builder = new Headers.Builder();
for (String header : headers) {
int colon = header.indexOf(‘:’);
if (colon == -1 || colon == 0 || colon == header.length() - 1) {
throw methodError(method,
“@Headers value must be in the form “Name: Value”. Found: “%s””, header);
}
String headerName = header.substring(0, colon);
String headerValue = header.substring(colon + 1).trim();
if (“Content-Type”.equalsIgnoreCase(headerName)) {
try {
contentType = MediaType.get(headerValue);
} catch (IllegalArgumentException e) {
throw methodError(method, e, “Malformed content type: %s”, headerValue);
}
} else {
builder.add(headerName, headerValue);
}
}
return builder.build();
}

而对于 Headers 则是将传递进来的 Headers 列表解析为了对应的 Headers 对象。

对方法参数的处理
最后我们看看对方法参数的处理:

private @Nullable ParameterHandler<?> parseParameter( int p, Type parameterType, @Nullable Annotation[] annotations, boolean allowContinuation) { ParameterHandler<?> result = null;
if (annotations != null) {
for (Annotation annotation : annotations) {
// 对每个注解通过 parseParameterAnnotation 进行解析
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;
}

parseParamterAnnotation 方法的代码太长了,这里就不再贴了,它对方法的每个注解都进行了独有的处理,并返回了对应的 ParamterHandler

可以发现,RequestFactory.parseAnnotations 的主要作用就是完成对方法注解信息的解析,从而用于产生对应的 Request

ServiceMethod 的创建
之后我们接着看看 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;
if (isKotlinSuspendFunction) {
// 如果方法是 kotlin 中的 suspend 方法
Type[] parameterTypes = method.getGenericParameterTypes();
// 获取 Continuation 的范型参数,它就是 suspend 方法的返回值类型
Type responseType = Utils.getParameterLowerBound(0,
(ParameterizedType) parameterTypes[parameterTypes.length - 1]);
// 如果 Continuation 的范型参数是 Response,则说明它需要的是 Response,那么将 continuationWantsResponse 置为 true;
if (getRawType(responseType) == Response.class && responseType instanceof ParameterizedType) {
// Unwrap the actual body type from Response.
responseType = Utils.getParameterUpperBound(0, (ParameterizedType) responseType);
continuationWantsResponse = true;
} else {
// TODO figure out if type is nullable or not
// Metadata metadata = method.getDeclaringClass().getAnnotation(Metadata.class)
// Find the entry for method
// Determine if return type is nullable or not
}
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();
if (responseType == okhttp3.Response.class) {
throw methodError(method, “'”

  • getRawType(responseType).getName()
  • “’ is not a valid response body type. Did you mean ResponseBody?”);
    }
    if (responseType == Response.class) {
    throw methodError(method, “Response must include generic type (e.g., Response)”);
    }
    // TODO support Unit for Kotlin?
    if (requestFactory.httpMethod.equals(“HEAD”) && !Void.class.equals(responseType)) {
    throw methodError(method, “HEAD method must use Void as response type.”);
    }
    // 通过 createResponseConverter 方法创建 Converter对象
    Converter<ResponseBody, ResponseT> responseConverter =
    createResponseConverter(retrofit, method, responseType);
    okhttp3.Call.Factory callFactory = retrofit.callFactory;
    if (!isKotlinSuspendFunction) {
    // 不是suspend方法的话则直接创建并返回一个 CallAdapted 对象
    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>) callAdapter);
    } else {
    //noinspection unchecked Kotlin compiler guarantees ReturnT to be Object.
    return (HttpServiceMethod<ResponseT, ReturnT>) new SuspendForBody<>(requestFactory,
    callFactory, responseConverter, (CallAdapter<ResponseT, Call>) callAdapter,
    continuationBodyNullable);
    }
    }

这里的代码非常非常长,大致可归纳为下面的步骤:

1. 如果这个方法是 Kotlin 中的 suspend 方法,由于由协程实现,因此需要获取 Continuation 的范型参数,这个参数就是请求返回值的真正类型。
2. 如果 suspend 方法返回值是 Response,则说明它需要的是 Response 而不是具体的类型,那么将 continuationWantsResponse 置为 true;
3. 如果不是 suspend 方法,则返回值的范型参数的类型就是请求返回值的真正类型(Call<ReturnType>ReturnType 才是真正经过转换后需要的类型)。
4. 通过 createCallAdapter 方法创建 CallAdapter 对象,它是用于将 Call<ResponseT> 对象适配为需要的类型 ReturnT 对象的。
5. 拿到 CallAdapter 后,获取到了 Response 的类型,并进行了校验。
6. 通过 createResponseConverter 方法获取 Converter 对象,它可以完成从 ResponseBodyResponse 类型 ResponseT 的转换。
7. 如果并非 Kotlin 的 suspend 方法,则直接传入 CallAdapter 及 Converter,创建 CallAdapted 对象。
8. 否则根据 suspend 方法需要的是 Response 还是具体的类型,分别返回 SuspendForResponseSuspendForBody 对象。

可以发现,新版的 Retrofit 对 Kotlin 的协程进行了支持。HttpServiceMethod.parseAnnotations 的主要作用就是创建 CallAdapter 以及 Converter 对象,并构建对应 HttpServiceMethod

CallAdapter

CallAdapter 是用于将Call<R> 对象适配为需要的类型 T 对象的。它的声明如下:

public interface CallAdapter<R, T> {

// 返回 Response 的类型
Type responseType();
// 将 Call 转换为 T 类型
T adapt(Call call);
}

我们先看看 createCallAdapter 方法是如何对它创建的:

private static <ResponseT, ReturnT> CallAdapter<ResponseT, ReturnT> createCallAdapter(
Retrofit retrofit, Method method, Type returnType, Annotation[] annotations) {
try {
//noinspection unchecked
return (CallAdapter<ResponseT, ReturnT>) retrofit.callAdapter(returnType, annotations);
} catch (RuntimeException e) { // Wide exception range because factories are user code.
throw methodError(method, e, “Unable to create call adapter for %s”, returnType);
}
}

它调用了 retrofit.callAdapter 方法:

public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) {
return nextCallAdapter(null, returnType, annotations);
}

之后调用到 retrofit.nextCallAdapter 方法:

public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType,
Annotation[] annotations) {
Objects.requireNonNull(returnType, “returnType == null”);
Objects.requireNonNull(annotations, “annotations == null”);
int start = callAdapterFactories.indexOf(skipPast) + 1;
for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
// 遍历 callAdapterFactories,尝试创建 CallAdapter
CallAdapter<?, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this);
if (adapter != null) {
return adapter;
}
}
// …不存在对应的 CallAdapterFactory,抛出异常
}

这里实际上是遍历了创建 Retrofit 对象时传递的 CallAdapter.Factory 列表尝试去创建 CallAdapter。如果这些 CallAdapter.Factory 都无法处理这个对应的 returnType 以及 annotations 的话,则会抛出异常。(前面 Factory 的优先级更高)

Retrofit 中有一个默认的 CallAdapter 工厂 DefaultCallAdapterFactory它的优先级比所有自定义工厂要低,它在创建时会传入一个 Executor,我们可以看到它的 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 or Call<? extends Foo>"); } final Type responseType = Utils.getParameterUpperBound(0, (ParameterizedType) returnType); final Executor executor = Utils.isAnnotationPresent(annotations, SkipCallbackExecutor.class) ? null: callbackExecutor; return new CallAdapter

可以看到,在没有 Executor 时,它不对 Call 进行修改,在有指定 Executor 时,则会将其包装为 ExecutorCallbackCall。一般来说这个 Executor 就是创建 Retrofit 时指定的 callbackExecutor

这个 callbackExecutor 实际上是用来指定调用 Callback 的线程的,从而使得 Callback 并不一定是在主线程被回调:

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) {
Objects.requireNonNull(callback, “callback == null”);
// 对 Callback 进行了包装,通过 callbackExecutor 进行回调
delegate.enqueue(new Callback() {
@Override public void onResponse(Call call, final Response response) {
callbackExecutor.execute(() -> {
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(() -> callback.onFailure(ExecutorCallbackCall.this, t));
}
});
}
// …
}

可以看到,这里实际上只是对 Callback 进行了包装,通过传递的 Executor 进行回调,从而对 callbackExecutor 进行支持。

Converter

接着我们看看 Converter 类,它是一个接口,用于将类型 F 的数据转换为类型 T:

public interface Converter<F, T> {
@Nullable T convert(F value) throws IOException;
// …
}

接着我们看看 createResponseConverter 是如何对它进行创建的:

private static Converter<ResponseBody, ResponseT> createResponseConverter(
Retrofit retrofit, Method method, Type responseType) {
Annotation[] annotations = method.getAnnotations();
try {
return retrofit.responseBodyConverter(responseType, annotations);
} catch (RuntimeException e) { // Wide exception range because factories are user code.
throw methodError(method, e, “Unable to create converter for %s”, responseType);
}
}

转调到了 retrofit.responseBodyConverter

public Converter<ResponseBody, T> responseBodyConverter(Type type, Annotation[] annotations) {
return nextResponseBodyConverter(null, type, annotations);
}

转调到了 nextResponseBodyConverter

public Converter<ResponseBody, T> nextResponseBodyConverter(
@Nullable Converter.Factory skipPast, Type type, Annotation[] annotations) {
Objects.requireNonNull(type, “type == null”);
Objects.requireNonNull(annotations, “annotations == null”);
int start = converterFactories.indexOf(skipPast) + 1;
for (int i = start, count = converterFactories.size(); i < count; i++) {
Converter<ResponseBody, ?> converter =
converterFactories.get(i).responseBodyConverter(type, annotations, this);
if (converter != null) {
//noinspection unchecked
return (Converter<ResponseBody, T>) converter;
}
}
// 没有找到对应的 ConverterFactory 进行处理,抛出异常
}

可以看到,这里与 CallAdapter 工厂类似,遍历创建 Retrofit 时传入的 Converter.Factory 列表,尝试进行创建,如果没有工厂能对其进行处理,抛出异常。(前面 Factory 的优先级更高)

Retrofit 中内置了两个 Converter.Factory,分别是 BuiltInConverters 以及 OptionalConverterFactory

其中 BuiltInConverters 的优先级比所有自定义工厂要高,以避免其他工厂覆盖它的方法,而 OptionalConverterFactory 的优先级比所有自定义工厂的优先级更低。

BuiltInConverters 中实现了多个转换器如将 ResponseBody 转换为 Void 或 Unit,将 Object 转换为 String 等。

OptionalConverterFactory 是通过 platform 获取到的 defaultConverterFactories,它是为了支持 Java 8 的 Optional 而实现的,Optional 是 Java 8 引入的用来解决空指针异常的类。

ServiceMethod

接着我们看看之前创建的 ServiceMethod 类,它是一个抽象类,需要子类对 invoke 方法进行实现。

abstract class ServiceMethod {
abstract @Nullable T invoke(Object[] args);
}

它的子类就是前面提到的 HttpServiceMethod

HttpServiceMethod

abstract class HttpServiceMethod<ResponseT, ReturnT> extends ServiceMethod {
@Override final @Nullable ReturnT invoke(Object[] args) {
Call call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
return adapt(call, args);
}

protected abstract @Nullable ReturnT adapt(Call call, Object[] args);
}

HttpServiceMethod 的 invoke 方法非常简单,它构造了一个 OkHttpCall,然后通过 adapt 这个虚函数来实现对 Call 的转换。它的子类只需要实现 adapt 从而对 Call 进行转换即可。

它共有三个子类,首先就是并非使用协程的情况下的 CallAdapted 类,另外两个子类则是在使用协程的情况下为了配合协程的 SuspendForResponse 以及 SuspendForBody

CallAdapted

CallAdapted 类继承自 HttpServiceMethod 类,并通过传递进来的 CallAdapter 对 Call 进行了转换。

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 call, Object[] args) {
return callAdapter.adapt(call);
}
}

SuspendForResponse

SuspendForResponse 类首先根据传递进来的 Call 构造了一个参数为 Response<ResponseT>Continuation 对象然后通过 Kotlin 实现的 awaitResponse 方法将 call 的 enqueue 异步回调过程封装为了一个 suspend 的函数。

static final class SuspendForResponse extends HttpServiceMethod<ResponseT, Object> {
private final CallAdapter<ResponseT, Call> callAdapter;
SuspendForResponse(RequestFactory requestFactory, okhttp3.Call.Factory callFactory,
Converter<ResponseBody, ResponseT> responseConverter,
CallAdapter<ResponseT, Call> callAdapter) {
super(requestFactory, callFactory, responseConverter);
this.callAdapter = callAdapter;
}

@Override protected Object adapt(Call call, Object[] args) {
call = callAdapter.adapt(call);
//noinspection unchecked Checked by reflection inside RequestFactory.
Continuation<Response> continuation =
(Continuation<Response>) args[args.length - 1];
// See SuspendForBody for explanation about this try/catch.
try {
return KotlinExtensions.awaitResponse(call, continuation);
} catch (Exception e) {
return KotlinExtensions.suspendAndThrow(e, continuation);
}
}
}

awaitResponse 方法如下:

suspend fun Call.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)
}
})
}
}

可以看到,分别通过在 onResponseonFailure 中调用 continuation.resumecontinuation.resumeWithException 从而对协程进行支持。

最后

**要想成为高级安卓工程师,必须掌握许多基础的知识。**在工作中,这些原理可以极大的帮助我们理解技术,在面试中,更是可以帮助我们应对大厂面试官的刁难。



《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!
n {
cancel()
}
enqueue(object : Callback {
override fun onResponse(call: Call, response: Response) {
continuation.resume(response)
}
override fun onFailure(call: Call, t: Throwable) {
continuation.resumeWithException(t)
}
})
}
}

可以看到,分别通过在 onResponseonFailure 中调用 continuation.resumecontinuation.resumeWithException 从而对协程进行支持。

最后

**要想成为高级安卓工程师,必须掌握许多基础的知识。**在工作中,这些原理可以极大的帮助我们理解技术,在面试中,更是可以帮助我们应对大厂面试官的刁难。


[外链图片转存中…(img-kpYELmj2-1715260091804)]

[外链图片转存中…(img-9XqSEzFV-1715260091805)]
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值