public interface DemoHttpService {
@POST()
Call post(@Url String url, @HeaderMap Map header, @Body RequestBody body);
}
new Retrofit.builder().baseUrl("https://xxx.xxx").build().create(DemoHttpService.class).post("/yyy/zzz", map, body).execute()
这里主要分析各个类的作用,所以各个类均使用默认实现
public Retrofit build() {
// 默认情况下,主要的几个成员变量
// callFactory = new OkHttpClient();
// adapterFactories 仅包含 ExecutorCallAdapterFactory
// converterFactories 仅包含 BuiltInConverters
}
通过动态代理返回 T,也就是上面DemoHttpService中的Call
public T create(final Class service) {
// ...
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class[] { service },
new InvocationHandler() {
private final Platform platform = Platform.get();
@Override public Object invoke(Object proxy, Method method, @Nullable Object[] args)
throws Throwable {
// ...
ServiceMethod
生成的动态代理主要做3步
分别看一下
// loadServiceMethod,即调用new ServiceMethod.Builder<>(this, method).build()构造ServiceMethod实例
// 其中this是Retrofit类的实例,method是自定义的service中的方法
Builder(Retrofit retrofit, Method method) {
this.retrofit = retrofit; // Retrofit实例
this.method = method; // method实例
this.methodAnnotations = method.getAnnotations(); // 方法的注解,以上面的DemoHttpService为例,即"POST"
this.parameterTypes = method.getGenericParameterTypes(); // 方法参数的类型,以上面的DemoHttpService为例,即String, Map, RequestBody
this.parameterAnnotationsArray = method.getParameterAnnotations(); // 方法参数的注解,以上面的DemoHttpService为例,即Url, HeaderMap, Body
}
public ServiceMethod build() {
// 1. 创建CallAdapter
callAdapter = createCallAdapter();
responseType = callAdapter.responseType();
if (responseType == Response.class || responseType == okhttp3.Response.class) {
// ...
}
// 2. 创建ResponseConverter
responseConverter = createResponseConverter();
// 3. 解析方法的注解,HTTP method 如@GET, @POST等
for (Annotation annotation : methodAnnotations) {
parseMethodAnnotation(annotation);
}
// ...
// 4. 解析请求参数
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);
}
主要分为4步
1. 创建CallAdapter
2. 创建ResponseConverter
3. 解析方法的注解,HTTP method 如@GET, @POST等
4. 解析请求参数
分别看一下
创建CallAdapter
// 最后调用的是Retrofit.nextCallAdapter
public CallAdapter nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType,
Annotation[] annotations) {
// ...
int start = adapterFactories.indexOf(skipPast) + 1;
for (int i = start, count = adapterFactories.size(); i < count; i++) {
CallAdapter adapter = adapterFactories.get(i).get(returnType, annotations, this);
if (adapter != null) {
return adapter;
}
}
// ...
}
// 即调用到adapterFactories的get方法,如果没有设置自定义的factory的话,就是调用DefaultCallAdapterFactory
// 返回的就是一个CallAdapter实例
public CallAdapter get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
if (getRawType(returnType) != Call.class) {
return null;
}
final Type responseType = Utils.getCallResponseType(returnType);
return new CallAdapter>() {
@Override public Type responseType() {
return responseType;
}
@Override public Call adapt(Call call) {
return call;
}
};
}
创建ResponseConverter
// 创建ResponseConverter也是一样的,调用到Retrofit.nextResponseBodyConverter,默认的是Convert.Factory
// 实例是BuiltInConverters
public Converter responseBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
// 以DemoHttpService为例,annotations是POST,所以这里返回BufferingResponseBodyConverter.INSTANCE
if (type == ResponseBody.class) {
return Utils.isAnnotationPresent(annotations, Streaming.class)
? StreamingResponseBodyConverter.INSTANCE
: BufferingResponseBodyConverter.INSTANCE;
}
if (type == Void.class) {
return VoidResponseBodyConverter.INSTANCE;
}
return null;
}
解析方法的注解,HTTP method 如@GET, @POST等
// DemoHttpService中,只有POST,没有带查询参数,调用之后,只是对httpMethod和hasBody赋值
// 如果有参数的话,会再进行解析
private void parseHttpMethodAndPath(String httpMethod, String value, boolean hasBody) {
if (this.httpMethod != null) {
throw methodError("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("URL query string \"%s\" must not have replace block. "
+ "For dynamic query parameters use @Query.", queryParams);
}
}
this.relativeUrl = value;
this.relativeUrlParamNames = parsePathParameters(value);
}
解析请求参数
// DemoHttpService.post方法中的每个参数调用parseParameter
// 这个方法主要就是些if...else...分支,根据注解的不同,创建不同的ParameterHandler实现类的实例
// ParameterHandler这个接口包含一个方法
// apply(RequestBuilder builder, @Nullable T value) -- 用请求参数构造RequestBuilder,会在实际发送请求前构造
// 实现类有如下这些
ParameterHandler (retrofit2)
HeaderMap in ParameterHandler (retrofit2)
Body in ParameterHandler (retrofit2)
RawPart in ParameterHandler (retrofit2)
FieldMap in ParameterHandler (retrofit2)
QueryName in ParameterHandler (retrofit2)
QueryMap in ParameterHandler (retrofit2)
Path in ParameterHandler (retrofit2)
Query in ParameterHandler (retrofit2)
RelativeUrl in ParameterHandler (retrofit2)
PartMap in ParameterHandler (retrofit2)
Part in ParameterHandler (retrofit2)
Field in ParameterHandler (retrofit2)
Header in ParameterHandler (retrofit2)
针对上面的例子,解析参数之后,会创建3个对象,对应post方法的三个入参
parameterHandlers = {ParameterHandler[3]@6440}
0 = {ParameterHandler$RelativeUrl@6568}
1 = {ParameterHandler$HeaderMap@6539}
2 = {ParameterHandler$Body@6569}
这一步很简单
OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
// 创建ServiceMethod.callAdapter时,用的默认实现,也就是ExecutorCallAdapterFactory
// 所以return serviceMethod.callAdapter.adapt(okHttpCall);执行的就是ExecutorCallAdapterFactory.get.adapte
// 返回的就是ExecutorCallbackCall实例
public CallAdapter get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
if (getRawType(returnType) != Call.class) {
return null;
}
final Type responseType = Utils.getCallResponseType(returnType);
return new CallAdapter>() {
@Override public Type responseType() {
return responseType;
}
@Override public Call adapt(Call call) {
return new ExecutorCallbackCall<>(callbackExecutor, call);
}
};
}
通过Retrofit.create(DemoHttpService.class).post(// …)之后,得到了ExecutorCallbackCall实例,
接下来执行execute或者enqueue来发起同步/异步请求,实际执行的就是OkHttpCall。
以OkHttpCall.execute为例
@Override public Response execute() throws IOException {
okhttp3.Call call;
synchronized (this) {
// ...
call = rawCall;
if (call == null) {
try {
// 1. 首先创建OkHttp3.Call
call = rawCall = createRawCall();
} catch (IOException | RuntimeException e) {
// ...
}
}
}
if (canceled) {
call.cancel();
}
// 2. 执行请求解析
return parseResponse(call.execute());
}
private okhttp3.Call createRawCall() throws IOException {
Request request = serviceMethod.toRequest(args);
okhttp3.Call call = serviceMethod.callFactory.newCall(request);
if (call == null) {
throw new NullPointerException("Call.Factory returned null.");
}
return call;
}
Request toRequest(@Nullable Object... args) throws IOException {
// 1. 创建RequestBuilder实例
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[] handlers = (ParameterHandler[]) parameterHandlers;
int argumentCount = args != null ? args.length : 0;
if (argumentCount != handlers.length) {
throw new IllegalArgumentException("Argument count (" + argumentCount
+ ") doesn't match expected count (" + handlers.length + ")");
}
// 2. 用servicMethod里创建的ParameterHandler解析参数
for (int p = 0; p < argumentCount; p++) {
handlers[p].apply(requestBuilder, args[p]);
}
// 3. 调用Okhttp3.Request.Builder创建Reqeust
return requestBuilder.build();
}
这一步流程比较简单,解析响应并返回
Response 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) {
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);
}
ExceptionCatchingRequestBody catchingBody = new ExceptionCatchingRequestBody(rawBody);
try {
// 调用serviceMethod里的responseConverter解析请求
T body = serviceMethod.toResponse(catchingBody);
return Response.success(body, rawResponse);
} catch (RuntimeException e) {
// If the underlying source threw an exception, propagate that rather than indicating it was
// a runtime exception.
catchingBody.throwIfCaught();
throw e;
}
}