Retrofit 是现在比较常用的网络请求库了,它的可扩展性强,底层网络请求集成了 Okhttp,异步处理可集成 RxJava,内容解析可集成 Gson,Jackson 等。而且全面支持 Restful 请求,并且通过注解的方式,支持链式调用,使用简洁方便。
精妙的源码设计模式,内部层次分工明确,解耦性强。
它的使用核心是实现一个 Java 接口,用注解的方式来指定各种网络请求中的字段、方法等。
拿官网的例子来说明:
活生生的例子
public interface GitHubService { @GET ("users/{user}/repos" ) Call> listRepos(@Path ("user" ) String user); }
上面的例子,用了两个注解,分别是 @GET
和@Path
,由字面意思也可以看出,@GET
是指该方法是 HTTP 请求中的 GET 方法,@Path("user")
是指将请求 URL 中的 {user}
部分替换为传入的 user
参数。
我们来看看这两个注解的源码:
@Documented @Target (METHOD)@Retention (RUNTIME)public @interface GET { String value () default "" ; }
它使用了三个元注解,不再多解释。它的 value
指的是请求中的绝对 / 相对路径。
@Documented @Retention (RUNTIME)@Target (PARAMETER)public @interface Path { String value () ; boolean encoded () default false ; }
它有两个参数,一个是 value,一个是是否已经经过 URL encoded。
那么,retrofit 是如何将注解使用起来的呢?我们来看看它的原理。
Retrofit 实现原理
先上一张图,简单了解一下它的整体流程:
在创建 Retrofit 实例时,我们一般会按照下面的方式来创建实例:
Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://api.github.com/" ) .build(); GitHubService service = retrofit.create(GitHubService.class ) ;
build()
方法其实就是 Java 中比较典型的 Builder 设计模式,不过多解释,我们直接来看 create()
的源代码:
@SuppressWarnings ("unchecked" )public T create (final Class 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 { if (method.getDeclaringClass() == Object.class ) { return method.invoke(this , args); } if (platform.isDefaultMethod(method)) { return platform.invokeDefaultMethod(method, service, proxy, args); } return loadServiceMethod(method).invoke(args != null ? args : emptyArgs); } } ); }
我们从这几行代码可以看出,Retrofit 是使用了动态代理的方式创建了一个实现 service 接口的对象,当外部调用 service 接口方法,会调用 invoke 方法,然后加载当前 method 对应的 ServiceMethod,并调用该 ServiceMethod 的 invoke。ServiceMethod 是个抽象类,那么,这里实际上是调用了 ServiceMethod 某一个实现类的 invoke 方法。具体的我们会在后面分析。
先看看 validateServiceInterface()
方法:
private void validateServiceInterface (Class> service) { if (!service.isInterface()) { throw new IllegalArgumentException("API declarations must be interfaces." ); } Deque> check = new ArrayDeque<>(1 ); check.add(service); while (!check.isEmpty()) { Class> candidate = check.removeFirst(); if (candidate.getTypeParameters().length != 0 ) { StringBuilder message = new StringBuilder("Type parameters are unsupported on" ) .append(candidate.getName()); if (candidate != service) { message.append("which is an interface of" ) .append(service.getName()); throw new IllegalArgumentException(message.toString()); } Collections.addAll(check, candidate.getInterfaces()); } if (validateEagerly) { Platform platform = Platform.get(); for (Method method : service.getDeclaredMethods()) { if (!platform.isDefaultMethod(method) && !Modifier.isStatic(method.getModifiers())) { loadServiceMethod(method); } } } }
接下来看看在 create()
和validateServiceInterface()
都会调用到的 loadServiceMethod()
方法:
private final Map> 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 的一个抽象类,我们来看看它的源代码:
abstract class ServiceMethod <T > { 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); } abstract @Nullable T invoke (Object[] args) ; }
RequestFactory 是比较重要的一个类,它负责解析注解、构造 request 等,在后面会直接与 okhttp 进行交互,我们来看看它的源码:
final class RequestFactory { static RequestFactory parseAnnotations (Retrofit retrofit, Method method) { return new Builder(retrofit, method).build(); } private final Method method; private final HttpUrl baseUrl; final String httpMethod; private final @Nullable String relativeUrl; private final @Nullable Headers headers; private final @Nullable MediaType contentType; private final boolean hasBody; private final boolean isFormEncoded; private final boolean isMultipart; private final ParameterHandler>[] parameterHandlers; final boolean isKotlinSuspendFunction; ... static final class Builder { private static final String PARAM = "[a-zA-Z][a-zA-Z0-9_-]*" ; private static final Pattern PARAM_URL_REGEX = Pattern.compile("\\{(" + PARAM + ")\\}" ); private static final Pattern PARAM_NAME_REGEX = Pattern.compile(PARAM); ... 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 () { 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 ); } } 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 ); } ... } 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 ; } int question = value.indexOf('?' ); if (question != -1 && question < value.length() - 1 ) { 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); } private @Nullable ParameterHandler> parseParameter( int p, Type parameterType, @Nullable Annotation[] annotations, boolean allowContinuation) { ParameterHandler> result = null ; 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; } @Nullable private ParameterHandler> parseParameterAnnotation( int p, Type type, Annotation[] annotations, Annotation annotation) { if (annotation instanceof Url) { ... return new ParameterHandler.RelativeUrl(method, p); ... } else if (annotation instanceof Path) { ... return new ParameterHandler.Path<>(method, p, name, converter, path.encoded()); ... } else if (annotation instanceof Query) { Class> rawParameterType = Utils.getRawType(type); gotQuery = true ; if (Iterable.class .isAssignableFrom (rawParameterType )) { if (!(type instanceof ParameterizedType)) { throw parameterError(method, p, rawParameterType.getSimpleName() + "must include generic type (e.g.," + rawParameterType.getSimpleName() + ")" ); } ParameterizedType parameterizedType = (ParameterizedType) type; Type iterableType = Utils.getParameterUpperBound(0 , parameterizedType); Converter, String> converter = retrofit.stringConverter(iterableType, annotations); return new ParameterHandler.Query<>(name, converter, encoded).iterable(); } else if (rawParameterType.isArray()) { Class> arrayComponentType = boxIfPrimitive(rawParameterType.getComponentType()); Converter, String> converter = retrofit.stringConverter(arrayComponentType, annotations); return new ParameterHandler.Query<>(name, converter, encoded).array(); } else { Converter, String> converter = retrofit.stringConverter(type, annotations); return new ParameterHandler.Query<>(name, converter, encoded); } } else if (annotation instanceof Header) { ... return new ParameterHandler.Header<>(name, converter); ... } else if (annotation instanceof Field) { ... return new ParameterHandler.Field<>(name, converter, encoded); ... } else if (annotation instanceof Body) { ... return new ParameterHandler.Body<>(method, p, converter); } ... return null ; } }
从这几部分代码可以看出,最后 RequestFactory 的实例中,包含的是:
HTTP 请求的 BaseUrl
HTTP 请求的 RelativeUrl
HTTP 请求的方法
HTTP 请求的参数列表(可选)
HTTP 请求的 Body(可选)
HTTP 请求的 Headers(可选)
ParameterHandler 的 Array
这 ParameterHandler 是什么呢?我们来看看它的代码:
abstract class ParameterHandler <T > { abstract void apply (RequestBuilder builder, @Nullable T value) throws IOException ; final ParameterHandler> iterable() { return new ParameterHandler>() { @Override void apply (RequestBuilder builder, @Nullable Iterable values) throws IOException { if (values == null ) return ; for (T value : values) { ParameterHandler.this .apply(builder, value); } } }; } final ParameterHandler array () { return new ParameterHandler() { @Override void apply (RequestBuilder builder, @Nullable Object values) throws IOException { if (values == null ) return ; for (int i = 0 , size = Array.getLength(values); i < size; i++) { ParameterHandler.this .apply(builder, (T) Array.get(values, i)); } } }; } static final class RelativeUrl extends ParameterHandler <Object > { private final Method method; private final int p; RelativeUrl(Method method, int p) { this .method = method; this .p = p; } @Override void apply (RequestBuilder builder, @Nullable Object value) { if (value == null ) { throw Utils.parameterError(method, p, "@Url parameter is null." ); } builder.setRelativeUrl(value); } } }
可以看出,每一种 retrofit 自定义的注解(GET、POST、FIELD、Path)等,最终都会转化成一个 ParameterHandler 的实例,并实现 apply()
方法。apply()
方法中会传入 RequestBuild 的实例,这是产生 Request 的倒数第二步。
好,说了这么一大圈,我们还是得回到 ServiceMethod 类中。
生成了 RequestFactory 实例后,利用这个实例,又调用了 HttpServiceMethod.parseAnnotations()
方法,我们来看看这个类,以及其包含的方法:
abstract class HttpServiceMethod <ResponseT , ReturnT > extends ServiceMethod <ReturnT > { static HttpServiceMethod parseAnnotations ( Retrofit retrofit, Method method, RequestFactory requestFactory) { boolean isKotlinSuspendFunction = requestFactory.isKotlinSuspendFunction; boolean continuationWantsResponse = false ; boolean continuationBodyNullable = false ; Annotation[] annotations = method.getAnnotations(); Type adapterType; ... CallAdapter callAdapter = createCallAdapter(retrofit, method, adapterType, annotations); Type responseType = callAdapter.responseType(); ... ... Converter responseConverter = createResponseConverter(retrofit, method, responseType); 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); } } private static CallAdapter createCallAdapter ( Retrofit retrofit, Method method, Type returnType, Annotation[] annotations) { try { return (CallAdapter) retrofit.callAdapter(returnType, annotations); } catch (RuntimeException e) { throw methodError(method, e, "Unable to create call adapter for %s" , returnType); } } private static Converter createResponseConverter ( Retrofit retrofit, Method method, Type responseType) { Annotation[] annotations = method.getAnnotations(); try { return retrofit.responseBodyConverter(responseType, annotations); } catch (RuntimeException e) { throw methodError(method, e, "Unable to create converter for %s" , responseType); } } @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) ; static final class CallAdapted <ResponseT , ReturnT > extends HttpServiceMethod <ResponseT , ReturnT > { 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); } } static final class SuspendForResponse <ResponseT > extends HttpServiceMethod <ResponseT , Object > { 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 { return KotlinExtensions.awaitResponse(call, continuation); } catch (Exception e) { return KotlinExtensions.suspendAndThrow(e, continuation); } } } }
HttpServiceMethod 类的主要功能,是创建了一个 CallAdapter 对象,这个对象是用来把 OkHttpCall 适配为我们定义的方法的返回值类型的;创建 Converter 对象,用于把 ResponseBody 转换为我们最终需要的类型;生成 HttpServiceMethod 的三种派生类其中一种的实例,返回并放到 serviceMethodCashe 中。
上面的代码中有两处比较重要的地方,用序号标注了出来,我们来单独讲讲:
灵魂 ❶ CallAdapter
跟着 retrofit.callAdapter()
向下走,我们看到了它的代码:
public CallAdapter, ?> callAdapter(Type returnType, Annotation[] annotations) { return nextCallAdapter(null , returnType, annotations); }public CallAdapter, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType, Annotation[] annotations) { ... 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; } } ... }public static final class Builder { Builder(Retrofit retrofit) { for (int i = 0 , size = retrofit.callAdapterFactories.size() - platform.defaultCallAdapterFactoriesSize(); i < size; i++) { callAdapterFactories.add(retrofit.callAdapterFactories.get(i)); } } public Retrofit build () { ... ... Executor callbackExecutor = this .callbackExecutor; if (callbackExecutor == null ) { callbackExecutor = platform.defaultCallbackExecutor(); } List callAdapterFactories = new ArrayList<>(this .callAdapterFactories); callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor)); ... return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories), unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly); } }
再看看 Platform.defaultCallAdapterFactories()做了些什么:
List extends CallAdapter.Factory> defaultCallAdapterFactories( @Nullable Executor callbackExecutor) { DefaultCallAdapterFactory executorFactory = new DefaultCallAdapterFactory(callbackExecutor); return hasJava8Types ? asList(CompletableFutureCallAdapterFactory.INSTANCE, executorFactory) : singletonList(executorFactory); }
然后我们看看 DefautCallAdapterFactory 类,顾名思义,它是创建 CallAdapter 的一个工厂类:
final class DefaultCallAdapterFactory extends CallAdapter .Factory { ... @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>() { @Override public Type responseType () { return responseType; } @Override public Call adapt (Call call) { return executor == null ? call : new ExecutorCallbackCall<>(executor, call); } }; } ... }
CallAdapter 的实现类终于处是找到了,但是它的 adapt() 方法才是真正起作用的方法。从上到下,调用到 adapt()
的时候,返回的是一个 ExcutorCallbackCall 的实例。
特性 ❷ Converter
跟着 retrofit.responseBodyConverter()
方法往下走,我们看到了它的代码:
public Converter responseBodyConverter (Type type, Annotation[] annotations) { return nextResponseBodyConverter(null , type, annotations); }public Converter nextResponseBodyConverter ( @Nullable Converter.Factory skipPast, Type type, Annotation[] annotations) { ... int start = converterFactories.indexOf(skipPast) + 1 ; for (int i = start, count = converterFactories.size(); i < count; i++) { Converter converter = converterFactories.get(i).responseBodyConverter(type, annotations, this ); if (converter != null ) { return (Converter) converter; } } }public static final class Builder { Builder(Retrofit retrofit) { for (int i = 1 , size = retrofit.converterFactories.size() - platform.defaultConverterFactoriesSize(); i < size; i++) { converterFactories.add(retrofit.converterFactories.get(i)); } } public Retrofit build () { ... ... List converterFactories = new ArrayList<>( 1 + this .converterFactories.size() + platform.defaultConverterFactoriesSize()); converterFactories.add(new BuiltInConverters()); converterFactories.addAll(this .converterFactories); converterFactories.addAll(platform.defaultConverterFactories()); return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories), unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly); } }
List extends Converter.Factory> defaultConverterFactories() { return hasJava8Types ? singletonList(OptionalConverterFactory.INSTANCE) : emptyList(); }
可以看到,与 CallAdapter 的生成方式几乎一模一样。
invoke 阶段
OK,所有初始化完成,接下来进入调用阶段,我们接着文章开头的例子,来看一下调用的入口:
... GitHubService service = retrofit.create(GitHubService.class ) ; Call> call = service.listRepos("cy198706" ); call.enqueue(new Callback>() { @Override public void onResponse (Call> call, Response> response)
{ } @Override public void onFailure (Call> call, Throwable t)
{ } });
那么,我们就以 enqueue()
方法为入口,看看调用的流程是怎样的。
刚才经过我们的分析,目前的 call
变量应该是一个 ExecutorCallbackCall 的实例,我们来看看它的代码:
static final class ExecutorCallbackCall <T > implements Call <T > { 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" ); delegate.enqueue(new Callback() { @Override public void onResponse (Call call, final Response response) { callbackExecutor.execute(() -> { if (delegate.isCanceled()) { 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)); } }); } @Override public boolean isExecuted () { return delegate.isExecuted(); } @Override public Response execute () throws IOException { return delegate.execute(); } @Override public void cancel () { delegate.cancel(); } @Override public boolean isCanceled () { return delegate.isCanceled(); } @SuppressWarnings ("CloneDoesntCallSuperClone" ) @Override public Call clone () { return new ExecutorCallbackCall<>(callbackExecutor, delegate.clone()); } @Override public Request request () { return delegate.request(); } @Override public Timeout timeout () { return delegate.timeout(); } }
delegate 是 OkHttpCall 对象,使用过 OkHttp 的应该知道它的 enqueue 是执行在子线程的,所以 ExecutorCallbackCall 为我们做的就是把在子线程的回调中,通过 MainThreadExecutor 在主线程中调用 retrofit2.Callback 的回调。当然这个 enqueue 还不是真正的 OkHttp 的 enqueue,它做了封装。
接着就看看 OkHttpCall.enqueue()
方法:
@Override public void enqueue (final Callback callback) { ... 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(); } 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(); } } @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(); } } }); }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; }
看到这里,不禁感叹,Retrofit 的工厂模式真是应用得出神入化,无论是 Call,还是 Request,全部用工厂模式来创建。
在上面我们讲过,RequestFactory 的一个重要功能是 parseAnnotation()
,现在它的另一个重要功能来了——构建 Request。
okhttp3.Request create (Object[] args) throws IOException { @SuppressWarnings ("unchecked" ) ParameterHandler[] handlers = (ParameterHandler[]) parameterHandlers; int argumentCount = args.length; if (argumentCount != handlers.length) { throw new IllegalArgumentException("Argument count (" + argumentCount + ") doesn't match expected count (" + handlers.length + ")" ); } RequestBuilder requestBuilder = new RequestBuilder(httpMethod, baseUrl, relativeUrl, headers, contentType, hasBody, isFormEncoded, isMultipart); if (isKotlinSuspendFunction) { argumentCount--; } List 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 () ; } }
此时,有了 Request,就可以真正地调用 Okhttp.enqueue()
方法来进行请求了。
在有了正确的回调结果后,还需要有一步 response = parseResponse(rawResponse)
来解析数据,我们看看它是如何做的:
Response parseResponse (okhttp3.Response rawResponse) throws IOException { ResponseBody rawBody = rawResponse.body(); rawResponse = rawResponse.newBuilder() .body(new NoContentResponseBody(rawBody.contentType(), rawBody.contentLength())) .build(); int code = rawResponse.code(); if (code < 200 || code >= 300 ) { try { 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 { T body = responseConverter.convert(catchingBody); return Response.success(body, rawResponse); } catch (RuntimeException e) { catchingBody.throwIfCaught(); throw e; } }
回调操作,这里还是在子线程,通过 ExecutorCallbackCall 里面的流程,调用到主线程,到这里我们就真正的走过了一次 Retrofit 从 create 创建 Call 到发送请求,然后到回调主线程的操作了。
至此,整个 Retrofit 的一次完整的流程便完成了,我们使用下面一张图来总结一下:
创建 Retrofit 实例阶段
调用new Retrofit.Builder().build()
Retrofit 类在 build()
方法中有如下步骤:
创建 OkHttpClient 实例
MainThreadExecutor 实例
调用 Platform.defaultCallAdapterFactories()
方法创建 CallAdapter
调用 Platform.defaultConverterFactoriesSize()
方法创建 Converter
新建并返回 Retrofit 实例
创建接口代理阶段
调用 Retrofit.create()
方法创建接口实例
在 Retrofit.create()
方法中有如下步骤:
检查接口
调用 loadServiceMethod()
方法
创建一个方法代理并返回
在 loadServiceMethod()
方法中有如下步骤:
解析注解
解析参数
生成 RequestFactory 实例
调用 HttpServiceMethod.parseAnnotations()
方法
在 HttpServiceMethod.parseAnnotations()
方法中有如下步骤:
调用 createCallAdapter()
方法,从 Retrofit 实例的 callAdapterFactories 中拿取 CallAdapter
返回 HttpServiceMethod 的派生类 CallAdapted | SuspendForResponse | SuspendForBody 的实例
将上一步返回的实例添加到缓存中等待读取和调用
触发代理机制阶段
调用接口方法,触发代理机制
在代理的 invoke()
方法被调用时,有如下步骤:
使用 loadServiceMethod()
获取该方法对应的 ServiceMethod
调用 ServiceMethod.invoke()
方法
调用 HttpServiceMethod.invoke()
方法
调用 HttpServiceMethod 的 adapt()
方法,其派生类之一的 adapt()
方法被调用
CallAdapter.adapt()
被调用
返回 ExecutorCallbackCall 实例
请求阶段
调用 ExecutorCallbackCall.enqueue()
方法发起请求
在 ExecutorCallbackCall.enqueue()
方法中有如下步骤:
创建 Request 实例,并调用 callFactory.newCall(Request)
方法创建 RealCall 实例
调用 RealCall.enqueue()
方法,使用 okhttp 发起请求
回调到主线程
解析并利用 Converter 反序列化返回的结果
回调到调用者