前言
很早之前就开始接触Retrofit,自己也写了一个项目,但是一直没有深入研究过源码。
正文
版本
v2.0.2
项目结构
源码文件并不多,所以相对看起来还是比较方便的。
接口
阅读源码,我认为可以先了解作者定义的接口,这样可以有助于我们把握整体的流程,而且优秀的代码也是依赖接口而不是具体的实现。所以要阅读好的三方框架,最好是先了解他的接口,非常有助于源码阅读。
这里主要有4个接口。我简单介绍。
Call
真正发出请求的对象接口
CallAdapter
可以把Call
对象转化为另外一个对象,如Observable
Callback
请求回调
Converter
把请求到的数据进行转化
先对所有的接口有个大致的了解
从一个简单的例子入手
var retrofit = Retrofit.Builder()
.baseUrl("http://www.baidu.com")
.build()
retrofit.create(TestApi::class.java)
.test("http://www.baidu.com")
.enqueue(object : Callback<ResponseBody> {
override fun onResponse(call: Call<ResponseBody>?, response: Response<ResponseBody>?) {
}
override fun onFailure(call: Call<ResponseBody>?, t: Throwable?) {
}
})
...
interface TestApi{
@GET
fun test(@Url url:String):Call<ResponseBody>
}
第一步: Retrofit构建
从上面例子中可以看出,创建Retrofit
时候,只有添加有一个必须添加的baseUrl
public Retrofit build() {
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new OkHttpClient();
}
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
// Make a defensive copy of the adapters and add the default Call adapter.
List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);
adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
// Make a defensive copy of the converters.
List<Converter.Factory> converterFactories = new ArrayList<>(this.converterFactories);
return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,
callbackExecutor, validateEagerly);
}
除了可以添加baseUrl,其实还有2个可选的参数可以添加。
- Convert 的实现对象的工厂类
- CallAdapter的实现对象的工厂类
为了先最简单地了解整个源码的流程,所以这些可选的参数我都先不加。
可以从上面的build
的代码中,可以看出,会创建一个
List<CallAdapter.Factory>
和List<Converter.Factory>
用来存放传进来的参数。所以我们可以知道,Retrofit是可以传入多个CallAdapter.Factory
和Converter.Factory
但是这里我们先不管,先往下走。
第二步:使用create创建方法接口
public <T> T create(final Class<T> service) {
Utils.validateServiceInterface(service);
if (validateEagerly) {
eagerlyValidateMethods(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, Object... args)
throws Throwable {
// If the method is a method from Object then defer to normal invocation.
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
ServiceMethod serviceMethod = loadServiceMethod(method);
OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);
}
});
}
使用Proxy.newProxyInstance
创建了方法接口的一个代理对象,调用接口的方法的时候会进入invoke
回调。
在返回这个代理对象之前,其实还有几行代码,我们可以简单看下
- 判断接口是否合法,方法数是否>0
Utils.validateServiceInterface(service)
static <T> void validateServiceInterface(Class<T> service) {
if (!service.isInterface()) {
throw new IllegalArgumentException("API declarations must be interfaces.");
}
if (service.getInterfaces().length > 0) {
throw new IllegalArgumentException("API interfaces must not extend other interfaces.");
}
}
- 预先加载接口中所有方法
eagerlyValidateMethods(service);
private void eagerlyValidateMethods(Class<?> service) {
Platform platform = Platform.get();
for (Method method : service.getDeclaredMethods()) {
if (!platform.isDefaultMethod(method)) {
loadServiceMethod(method);
}
}
}
第三步:调用接口中的方法
由第二步,我们可以知道,其实调用接口的方法,其实最后是调用了刚才创建的代理对象中的方法,然后进入了invoke
方法。所以调用的其实是这一段代码。(一般情况下,是调用下面代码,但是也有一些例外,这里就不多介绍了)
ServiceMethod serviceMethod = loadServiceMethod(method);
OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);
由于这3行代码是最最关键的部分,这里做详细的分析。
- 加载接口方法
ServiceMethod serviceMethod = loadServiceMethod(method);
ServiceMethod loadServiceMethod(Method method) {
ServiceMethod result;
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
result = new ServiceMethod.Builder(this, method).build();
serviceMethodCache.put(method, result);
}
}
return result;
}
通过反射的Method
对象获取一个ServiceMethod
对象。
注意:ServiceMethod: Adapts an invocation of an interface method into an HTTP call
首先会先从cache中获取一个ServiceMethod
,如果没有,就创建一个新的ServiceMethod
,再存入cache.
前面已经介绍了,就是ServiceMethod
可以进行预先加载,默认使用懒加载,就是调用的时候再去加载,如果对方法调用有时间要求,可以使用预先加载,减少一些时间。
下面来看下ServiceMethod的创建
public ServiceMethod build() {
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?");
}
responseConverter = createResponseConverter();
for (Annotation annotation : methodAnnotations) {
parseMethodAnnotation(annotation);
}
if (httpMethod == null) {
throw methodError("HTTP method annotation is required (e.g., @GET, @POST, etc.).");
}
if (!hasBody) {
if (isMultipart) {
throw methodError(
"Multipart can only be specified on HTTP methods with request body (e.g., @POST).");
}
if (isFormEncoded) {
throw methodError("FormUrlEncoded can only be specified on HTTP methods with "
+ "request body (e.g., @POST).");
}
}
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);
}
if (relativeUrl == null && !gotUrl) {
throw methodError("Missing either @%s URL or @Url parameter.", httpMethod);
}
if (!isFormEncoded && !isMultipart && !hasBody && gotBody) {
throw methodError("Non-body HTTP method cannot contain @Body.");
}
if (isFormEncoded && !gotField) {
throw methodError("Form-encoded method must contain at least one @Field.");
}
if (isMultipart && !gotPart) {
throw methodError("Multipart method must contain at least one @Part.");
}
return new ServiceMethod<>(this);
}
创建ServiceMethod
一共是2个参数,一个是Retrofit
对象,一个是Method
对象。
可以看到,这个方法中抛出了很多错误,如果使用过retrofit
的人,可以看出,都是一些很常见的错误,大部分是注解用错了。
这里最重要的内容有3点
- 创建CallAdapter对象
- 创建Converter对象
- 对接口方法的注释进行解析
我们一个个来看下:
callAdapter = createCallAdapter();
private CallAdapter<?> createCallAdapter() {
Type returnType = method.getGenericReturnType();
if (Utils.hasUnresolvableType(returnType)) {
throw methodError(
"Method return type must not include a type variable or wildcard: %s", returnType);
}
if (returnType == void.class) {
throw methodError("Service methods cannot return void.");
}
Annotation[] annotations = method.getAnnotations();
try {
return retrofit.callAdapter(returnType, annotations);
} catch (RuntimeException e) { // Wide exception range because factories are user code.
throw methodError(e, "Unable to create call adapter for %s", returnType);
}
}
...
retrofit.callAdapter(returnType, annotations)
public CallAdapter<?> callAdapter(Type returnType, Annotation[] annotations) {
return nextCallAdapter(null, returnType, annotations);
}
/**
* Returns the {@link CallAdapter} for {@code returnType} from the available {@linkplain
* #callAdapterFactories() factories} except {@code skipPast}.
*
* @throws IllegalArgumentException if no call adapter available for {@code type}.
*/
public CallAdapter<?> nextCallAdapter(CallAdapter.Factory skipPast, Type returnType,
Annotation[] annotations) {
checkNotNull(returnType, "returnType == null");
checkNotNull(annotations, "annotations == null");
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;
}
}
StringBuilder builder = new StringBuilder("Could not locate call adapter for ")
.append(returnType)
.append(".\n");
if (skipPast != null) {
builder.append(" Skipped:");
for (int i = 0; i < start; i++) {
builder.append("\n * ").append(adapterFactories.get(i).getClass().getName());
}
builder.append('\n');
}
builder.append(" Tried:");
for (int i = start, count = adapterFactories.size(); i < count; i++) {
builder.append("\n * ").append(adapterFactories.get(i).getClass().getName());
}
throw new IllegalArgumentException(builder.toString());
}
创建CallAdapter
主要调用Retrofit
中的nextCallAdapter
,从adapterFactories
中获取一个Factory去创建对应的CallAdapter.如果adapterFactories
中所有的Factory
都无法创建对应的CallAdapter
则会报错。
前面介绍到adapterFactories
,其实是可以在构建Retrofit
对象的时候传入的。但是我们在前面并未传入CallAdapter.Factory
,会不会直接报错呢?不会。
public Retrofit build() {
...
List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);
adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
...
}
}
在创建adapterFactories
对象时,会预先在里面添加一个默认的CallAdapter.Factory
。
创建Convert的过程和CallAdapter是一致的,我就不过多介绍了
Builder(Platform platform) {
this.platform = platform;
// 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());
}
...
List<Converter.Factory> converterFactories = new ArrayList<>(this.converterFactories);
...
这里稍微有点不太一样的地方是,直接在创建Retrofit.Build
对象的时候,就先把默认的Convert
也就是BuiltInConverters
添加到了converterFactories
中。
由于Retrofit
的注解比较多,所以对接口方法进行解析的过程也比较复杂。也不是整个框架的重点,所以我这里简单介绍下,其中有些地方还是值得我们去学习的。
解析注释,一共分2部分,一个是解析方法上的注释,一个是解析参数上的注释。
public ServiceMethod build() {
...
for (Annotation annotation : methodAnnotations) {
parseMethodAnnotation(annotation);
}
...
for (int p = 0; p < parameterCount; p++) {
...
parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);
}
...
return new ServiceMethod<>(this);
}
- 方法上的注释:
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);
if (!Void.class.equals(responseType)) {
throw methodError("HEAD method must use Void as response type.");
}
} 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("@Headers annotation is empty.");
}
headers = parseHeaders(headersToParse);
} else if (annotation instanceof Multipart) {
if (isFormEncoded) {
throw methodError("Only one encoding annotation is allowed.");
}
isMultipart = true;
} else if (annotation instanceof FormUrlEncoded) {
if (isMultipart) {
throw methodError("Only one encoding annotation is allowed.");
}
isFormEncoded = true;
}
}
方法上的注释,确实是没啥好说的,就是判断不同的注解进行不同的解析,然后给自己的一些当前变量赋值。我就不说了。
- 方法参数上的注释
parseParameter
private ParameterHandler<?> parseParameter(
int p, Type parameterType, Annotation[] annotations) {
ParameterHandler<?> result = null;
for (Annotation annotation : annotations) {
ParameterHandler<?> annotationAction = parseParameterAnnotation(
p, parameterType, annotations, annotation);
if (annotationAction == null) {
continue;
}
if (result != null) {
throw parameterError(p, "Multiple Retrofit annotations found, only one allowed.");
}
result = annotationAction;
}
if (result == null) {
throw parameterError(p, "No Retrofit annotation found.");
}
return result;
}
我就不再深入了,简单点说就是把参数上的注释转化为ParameterHandler
对象。来看下ParameterHandler
对象是啥。
abstract class ParameterHandler<T> {
abstract void apply(RequestBuilder builder, T value) throws IOException;
final ParameterHandler<Iterable<T>> iterable() {
return new ParameterHandler<Iterable<T>>() {
@Override void apply(RequestBuilder builder, Iterable<T> values) throws IOException {
...
};
}
final ParameterHandler<Object> array() {
return new ParameterHandler<Object>() {
@Override void apply(RequestBuilder builder, Object values) throws IOException {
...
}
};
}
static final class RelativeUrl extends ParameterHandler<Object> {
@Override void apply(RequestBuilder builder, Object value) {
builder.setRelativeUrl(value);
}
}
static final class Header<T> extends ParameterHandler<T> {
...
}
static final class Path<T> extends ParameterHandler<T> {
...
}
static final class Query<T> extends ParameterHandler<T> {
...
}
static final class QueryMap<T> extends ParameterHandler<Map<String, T>> {
...
}
static final class Field<T> extends ParameterHandler<T> {
...
}
static final class FieldMap<T> extends ParameterHandler<Map<String, T>> {
...
}
static final class Part<T> extends ParameterHandler<T> {
...
}
static final class RawPart extends ParameterHandler<MultipartBody.Part> {
...
}
static final class PartMap<T> extends ParameterHandler<Map<String, T>> {
...
}
static final class Body<T> extends ParameterHandler<T> {
...
}
所有的注解对应的都有自己的一个ParameterHandler
实现。然后在里面进行解析。
解析方法注释得到的参数,以及解析方法参数的注释得到的ParameterHandler
都是为了构建Request
对象,代码如下:
Request toRequest(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;
int argumentCount = args != null ? args.length : 0;
if (argumentCount != handlers.length) {
throw new IllegalArgumentException("Argument count (" + argumentCount
+ ") doesn't match expected count (" + handlers.length + ")");
}
for (int p = 0; p < argumentCount; p++) {
handlers[p].apply(requestBuilder, args[p]);
}
return requestBuilder.build();
}
其中handlers[p].apply(requestBuilder, args[p]);
是循环调用ParameterHandler
这个抽象类的抽象方法。这里是值得我们学习的,依赖抽象类和接口,而不依赖具体的实现。
下面我们可以再回过头来看
/** Adapts an invocation of an interface method into an HTTP call. */
官方对ServiceMethod
的说明。
其实就我个人理解,是不是改成
/** Adapts an invocation of an interface method into an HTTP request. */
会更好点,因为ServiceMethod
是把接口方法最终转化为一个Request
对象而不是一个Call
对象,当然也只是个人的理解。
- 创建OkHttpCall对象
OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
OkHttpCall(ServiceMethod<T> serviceMethod, Object[] args) {
this.serviceMethod = serviceMethod;
this.args = args;
}
OkHttpCall的构造方法很简单,OkHttpCall实现了Call
接口。
- CallAdapter对Call对象进行转换
在介绍这个之前,我们再回顾下前面的默认的CallAdapter。
adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
这里需要了解Platform
class Platform {
..
}
static class Android extends Platform {
@Override public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
@Override CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {
return new ExecutorCallAdapterFactory(callbackExecutor);
}
static class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
@Override public void execute(Runnable r) {
handler.post(r);
}
}
}
static class IOS extends Platform {
...
}
}
对不同的平台进行不同的处理。这里肯定是Android
平台,所以应该调用Android
中的方法。
所以,默认的CallAdapter.Factory
是ExecutorCallAdapterFactory
下面我们继续刚才最重要的3句代码中的最后一句代码
return serviceMethod.callAdapter.adapt(okHttpCall);
final class ExecutorCallAdapterFactory extends CallAdapter.Factory {
...
@Override
public CallAdapter<Call<?>> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
if (getRawType(returnType) != Call.class) {
return null;
}
final Type responseType = Utils.getCallResponseType(returnType);
return new CallAdapter<Call<?>>() {
@Override public Type responseType() {
return responseType;
}
@Override public <R> Call<R> adapt(Call<R> call) {
return new ExecutorCallbackCall<>(callbackExecutor, call);
}
};
}
static final class ExecutorCallbackCall<T> implements Call<T> {
final Executor callbackExecutor;
final Call<T> delegate;
ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) {
this.callbackExecutor = callbackExecutor;
this.delegate = delegate;
}
@Override public void enqueue(final Callback<T> callback) {
if (callback == null) throw new NullPointerException("callback == null");
delegate.enqueue(new Callback<T>() {
@Override public void onResponse(Call<T> call, final Response<T> response) {
callbackExecutor.execute(new Runnable() {
@Override public void run() {
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<T> call, final Throwable t) {
callbackExecutor.execute(new Runnable() {
@Override public void run() {
callback.onFailure(ExecutorCallbackCall.this, t);
}
});
}
});
}
...
使用adapt
方法后,返回了ExecutorCallbackCall
这个对象
第四步:enqueue
发送请求(execute大同小异)
具体的代码请看上面,从ExecutorCallbackCall
开始。
前面一步步走下来,我们已经知道,调用接口方法后,真正返回的是ExecutorCallbackCall
对象。
调用enqueue
方法,其实是调用创建ExecutorCallbackCall
对象时传入的Call
对象。我们在前面第三步时解析了最关键的三句代码,了解到了其实这里的Call
对象,就是OkHttpCall
对象。
@Override public void enqueue(final Callback<T> callback) {
...
call = rawCall = createRawCall();
...
call.enqueue(new okhttp3.Callback() {
@Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse)
throws IOException {
...
response = parseResponse(rawResponse);
...
});
}
...
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;
}
...
Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
...
T body = serviceMethod.toResponse(catchingBody);
return Response.success(body, rawResponse);
...
}
其中最重要的2个方法就是
- createRawCall
- parseResponse
这里我们分别来分析下。
createRawCall
这里主要调用了serviceMethod.toRequest(args)
其实我们在前面已经介绍过了,ServiceMethod
中的toRequest
就是把前面解析完成的参数,转化为对应的Request
,这里就不多说了。
这里我们还要了解serviceMethod.callFactory
是什么?
ServiceMethod.java
...
ServiceMethod(Builder<T> builder) {
this.callFactory = builder.retrofit.callFactory();
...
}
Retrofit.java
...
public Builder client(OkHttpClient client) {
return callFactory(checkNotNull(client, "client == null"));
}
/**
* Specify a custom call factory for creating {@link Call} instances.
* <p>
* Note: Calling {@link #client} automatically sets this value.
*/
public Builder callFactory(okhttp3.Call.Factory factory) {
this.callFactory = checkNotNull(factory, "factory == null");
return this;
}
...
public Retrofit build() {
...
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new OkHttpClient();
}
...
...
由上代码可看出,ServiceMethod
中的callFactory
就是Retrofit
中的callFactory
,可以在构建Retrofit
对象的时候传入,不传入默认为OkHttpClient
。
所以
okhttp3.Call call = serviceMethod.callFactory.newCall(request);
这里的serviceMethod.callFactory
其实就是OkHttpClient
然后创建了一个Call
对象。真正发起请求的也是这个Call
对象。
这里可能会看起来有点糊涂,因为这里的Call
是okhttp3.Call
,而前面一直在说的Call
是retrofit2.Call
大家不要把这2个搞混了。
我们可以把这2个做一下对比会发现,它们的方法基本一致。
Retrofit
我们可以理解为在okhttp3
外面的一层封装,真正去发生http请求的还是原来的okhttp3
。
parseResponse
代码在上面已贴出,其中最重要的一句是:
T body = serviceMethod.toResponse(catchingBody);
...
this.responseConverter = builder.responseConverter;
...
T toResponse(ResponseBody body) throws IOException {
return responseConverter.convert(body);
}
...
使用Convert
对象把ResponseBody
转化为另一个对象。由代码可以看出,ServiceMethod
中的responseConverter
也是来自Retrofit
对象。也就是前面介绍的默认的Convert.Factory
对象,也就是BuiltInConverters
,产生的Convert
对象。
final class BuiltInConverters extends Converter.Factory {
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
if (type == ResponseBody.class) {
if (Utils.isAnnotationPresent(annotations, Streaming.class)) {
return StreamingResponseBodyConverter.INSTANCE;
}
return BufferingResponseBodyConverter.INSTANCE;
}
if (type == Void.class) {
return VoidResponseBodyConverter.INSTANCE;
}
return null;
}
在ServiceMethod
中会根据方法的返回类型,在里面获取到对应的Convert
对象。如果返回的类型没有相应的Convert
则会返回null。
Retrofit.java
public <T> Converter<ResponseBody, T> nextResponseBodyConverter(Converter.Factory skipPast,
Type type, Annotation[] annotations) {
checkNotNull(type, "type == null");
checkNotNull(annotations, "annotations == null");
int start = converterFactories.indexOf(skipPast) + 1;
for (int i = start, count = converterFactories.size(); i < count; i++) {
Converter<ResponseBody, ?> converter =
//**在这里真正去获取对应的Convert**
converterFactories.get(i).responseBodyConverter(type, annotations, this);
if (converter != null) {
//noinspection unchecked
return (Converter<ResponseBody, T>) converter;
}
}
StringBuilder builder = new StringBuilder("Could not locate ResponseBody converter for ")
.append(type)
.append(".\n");
if (skipPast != null) {
builder.append(" Skipped:");
for (int i = 0; i < start; i++) {
builder.append("\n * ").append(converterFactories.get(i).getClass().getName());
}
builder.append('\n');
}
builder.append(" Tried:");
for (int i = start, count = converterFactories.size(); i < count; i++) {
builder.append("\n * ").append(converterFactories.get(i).getClass().getName());
}
throw new IllegalArgumentException(builder.toString());
}
从代码中可以看出,如果返回为null,那么会从下一个Convert.Factory
中去获取对应的Convert
由于我们前面并未添加Convert.Factory
,所以这里只有一个默认的BuiltInConverters
,并且它只支持返回值是ResponseBody
,Void
这2种类型的或者注释中有Streaming
的方法,否者会报错。
第五步:在Callback接口中对转换后的对象进行处理
到了这一步的时候其实源码代码已经分析的差不多了。但是前面提到的默认的
CallAdapter.Factory
也就是ExecutorCallAdapterFactory
中其实有个细节刚才我没有细讲,现在可以回过去看。
@Override public void enqueue(final Callback<T> callback) {
if (callback == null) throw new NullPointerException("callback == null");
delegate.enqueue(new Callback<T>() {
@Override public void onResponse(Call<T> call, final Response<T> response) {
//**使用callbackExecutor去执行真正的callback中的onResponse和onFailure**
callbackExecutor.execute(new Runnable() {
@Override public void run() {
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<T> call, final Throwable t) {
callbackExecutor.execute(new Runnable() {
@Override public void run() {
callback.onFailure(ExecutorCallbackCall.this, t);
}
});
}
});
我们往回追溯,看下callbackExecutor
是什么
static class Android extends Platform {
@Override public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
@Override CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {
return new ExecutorCallAdapterFactory(callbackExecutor);
}
static class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
@Override public void execute(Runnable r) {
handler.post(r);
}
}
}
defaultCallbackExecutor
其实就是把Runnable
抛到主线程中去执行。
所以在我们自己的Callback中的onResponse
和onFailure
已经都是在主线程中执行了。
总结
Retrofit
的源码相对来说是比较少的,非常适合新手阅读(包括我),可以快速体验阅读源码的乐趣,感觉对整个框架的使用都会得心应手。
另外自己也感受到了阅读源码的3个好方法。
- 先了解所有的接口,对整个框架有个大致的了解
- 可以写一个简单的demo,一步步深入
- 从后往前,想要知道一个变量的由来,可以往前追溯