综述
Retrofit到一个实际请求/响应的过程包括
- 创建ServiceMethod,调用
ServiceMethod.build()
- 调用OkHttpCall(ServiceMethod,args)创建OkHttpCall对象,
- 调用 CallAdapter.adapt(okHttpCall)创建关联执行器Executor和Call的应用层Call类,Android默认为ExecutorCallbackCall
源码研究
- 创建ServiceMethod
ServiceMethod.build()
public ServiceMethod build() {
//通过Retrofit.nextCallAdapter获取callAdapter,有自定义就用自定义,没有就用默认ExecutorCallAdapterFactory
callAdapter = createCallAdapter();
responseType = callAdapter.responseType();
//返回类型验证
if (responseType == Response.class || responseType == okhttp3.Response.class) {
throw methodError("'"
+ Utils.getRawType(responseType).getName()
+ "' is not a valid response body type. Did you mean ResponseBody?");
}
//通过Retrofit.nextResponseBodyConverter处理转换异常,获得自定义转换器
responseConverter = createResponseConverter();
//解析自定义的注解成URL组件
for (Annotation annotation : methodAnnotations) {
parseMethodAnnotation(annotation);
}
//错误处理
...
//构建参数替换的辅助数组parameterHandlers
int parameterCount = parameterAnnotationsArray.length;
parameterHandlers = new ParameterHandler<?>[parameterCount];
for (int p = 0; p < parameterCount; p++) {
Type parameterType = parameterTypes[p];
if (Utils.hasUnresolvableType(parameterType)) {
throw parameterError(p, "Parameter type must not include a type variable or wildcard: %s",
parameterType);
}
Annotation[] parameterAnnotations = parameterAnnotationsArray[p];
if (parameterAnnotations == null) {
throw parameterError(p, "No Retrofit annotation found.");
}
parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);
}
//错误处理
...
return new ServiceMethod<>(this);
}
- 用户调用enqueue方法发起异步请求
ExecutorCallbackCall.enqueue()
@Override public void enqueue(final Callback<T> callback) {
checkNotNull(callback, "callback == null");
//调用OkhttpCall的enqueue方法,Executor执行响应结果
delegate.enqueue(new Callback<T>() {
}
});
}
OkHttpCall. enqueue
@Override public void enqueue(final Callback<T> callback) {
checkNotNull(callback, "callback == null");
okhttp3.Call call;
Throwable failure;
synchronized (this) {
...
//这里创建请求报文获得realCall
call = rawCall = createRawCall();
...
}
//realCall发起异步请求
call.enqueue(new okhttp3.Callback() {
...
//转换响应报文
response = parseResponse(rawResponse);
...
});
}
createRawCall
private okhttp3.Call createRawCall() throws IOException {
//创建request报文
Request request = serviceMethod.toRequest(args);
//获得okhttp.realCall
okhttp3.Call call = serviceMethod.callFactory.newCall(request);
if (call == null) {
throw new NullPointerException("Call.Factory returned null.");
}
return call;
}
serviceMethod.toRequest(args)
Request toRequest(@Nullable Object... args) throws IOException {
RequestBuilder requestBuilder = new RequestBuilder(httpMethod, baseUrl, relativeUrl, headers,
contentType, hasBody, isFormEncoded, isMultipart);
...
@SuppressWarnings("unchecked") // It is an error to invoke a method with the wrong arg types.
ParameterHandler<Object>[] handlers = (ParameterHandler<Object>[]) parameterHandlers;
//根据先前的parameterHandlers进行参数转换
for (int p = 0; p < argumentCount; p++) {
handlers[p].apply(requestBuilder, args[p]);
}
//创建request报文
return requestBuilder.build();
}
parseResponse
Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
ResponseBody rawBody = rawResponse.body();
//异常处理,200-299成功状态码,204和205没有响应body
...
//serviceMethod.toResponse用户转换器转换
T body = serviceMethod.toResponse(catchingBody);
return Response.success(body, rawResponse);
}
总结
通过梳理大体了解的Retrofit的整体结构和流程,当然还有很多的细节没有讨论,需要时可以查看相应的源码。
Retrofit源码本身并不复杂,但是Retrofit的架构设计,解耦所透露的架构经验,思想,规范等是非常值得我们学习和参照设计的。
网友评论