Retrofit源码解析

参考:

准备

和上次看okhttp的源码一样, 先把源码clone下来, 导入Intellij IDEA用maven构建

使用示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
.serializeNulls()
.create();

HttpLoggingInterceptor logger = new HttpLoggingInterceptor();
logger.setLevel(Level.BODY);
OkHttpClient client =
new Builder().addInterceptor(logger).connectTimeout(12, TimeUnit.SECONDS).build();
String baseUrl = "http://gank.io/";
Retrofit.Builder builder = new Retrofit.Builder().baseUrl(baseUrl)
.client(client)
.addCallAdapterFactory(
RxJavaCallAdapterFactory.createWithScheduler(Schedulers.io()))
.addConverterFactory(GsonConverterFactory.create(gson));
Retrofit retrofit = builder.build();
return retrofit;

同步请求

1
2
3
4
5
6
7
8
9
10
11
12
13
new Thread(new Runnable() {
@Override
public void run() {
GankApi gankApi = mRetrofit.create(GankApi.class);
final Call<MeizhiModel> call = gankApi.getMeiZhi(10, 1);
try {
MeizhiModel meizhiModel = call.execute().body();
Log.d(TAG, "meizhiModel = " + meizhiModel.toString());
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();

异步请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
GankApi gankApi = mRetrofit.create(GankApi.class);
Call<MeizhiModel> call = gankApi.getMeiZhi(10, 1);
call.enqueue(new Callback<MeizhiModel>() {
@Override
public void onResponse(Call<MeizhiModel> call, Response<MeizhiModel> response) {
Log.d(TAG, "currentThread = " + Thread.currentThread().getName());
Log.d(TAG, "response = " + response.body().toString());
}

@Override
public void onFailure(Call<MeizhiModel> call, Throwable t) {

}
});

Retrofit的创建

从这句代码我们点进去看

1
2
3
4
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(API_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
1
2
3
4
5
6
7
Builder(Platform platform) {
this.platform = platform;
}

public Builder() {
this(Platform.get());
}

看一下Platform.get()方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Platform {
private static final Platform PLATFORM = findPlatform();

static Platform get() {
return PLATFORM;
}

private static Platform findPlatform() {
try {
Class.forName("android.os.Build");
if (Build.VERSION.SDK_INT != 0) {
return new Android();
}
} catch (ClassNotFoundException ignored) {
}
try {
Class.forName("java.util.Optional");
return new Java8();
} catch (ClassNotFoundException ignored) {
}
return new Platform();
}
...

从上面的代码可以看出通过Class.forName反射获取类名的方式,来判断当前的平台是Android或者是java8又或者是一个默认的平台.
我们Android这个类, 可能后面要用到

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
static class Android extends Platform {
@Override public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}

@Override CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
if (callbackExecutor == null) throw new AssertionError();
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);
}
}
}

Retrofit.create

看一下这个方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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, @Nullable 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<Object, Object> serviceMethod =
(ServiceMethod<Object, Object>) loadServiceMethod(method);
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);
}
});
}

这个方法, 我们进去的是一个interface的字节码对象, 然后得到的是却是一个这个interface的对象, 代理类在程序运行前不存在、运行时由程序动态生成的代理方式称为动态代理。
关于动态代理, 我们还是写一个例子来理解比较好点
新建一个interface

1
2
3
public interface Flyable {
void fly();
}

再建一个委托类(也就是被代理的类)叫做Bird, 模拟鸟在空中飞行的时间, 动态代理要求委托类必须实现了某个接口,比如这里委托类Bird实现了Flyable

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Bird implements Flyable {

private static void sleep(long millSeconds) {
try {
Thread.sleep(millSeconds);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

@Override
public void fly() {
System.out.println("fly");
sleep(110);
}
}

现在我想要统计Bird的飞行时间, 要怎么做呢?
新建一个类实现InvocationHandler接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class TimingInvocationHandler implements InvocationHandler {

private Object target;

public TimingInvocationHandler() {}

public TimingInvocationHandler(Object target) {
this.target = target;
}

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
long start = System.currentTimeMillis();
Object obj = method.invoke(target, args);
System.out.println(method.getName() + " cost time is:" + (System.currentTimeMillis() - start));
return obj;
}
}

这里的这个target表示委托类对象, 从外部传进来, 也就是上面的Bird对象
InvocationHandler是负责连接代理类和委托类的中间类必须实现的接口。其中只有一个
public Object invoke(Object proxy, Method method, Object[] args)
proxy表示通过Proxy.newProxyInstance()生成的代理类对象
method表示代理对象被调用的函数
args表示代理对象被调用的函数的参数
调用代理对象的每个函数实际最终都是调用了InvocationHandler的invoke函数。这里我们在invoke实现中添加了开始结束计时,其中还调用了委托类对象target(也就是传进来的bird对象)的相应函数,这样便完成了统计执行时间的需求.
接下来通过 Proxy 类静态函数生成代理对象

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Main {

public static void main(String[] args) {
TimingInvocationHandler timingInvocationHandler =
new TimingInvocationHandler(new Bird());
Flyable flyable = (Flyable) (Proxy.newProxyInstance(Flyable.class.getClassLoader(),
new Class[] { Flyable.class }, timingInvocationHandler));
// 调用该代理对象的函数会调用到timingInvocationHandler的invoke方法
// 而invoke方法会去反射调用实现类的方法, 然后输出反射所花费的时间
flyable.fly();
System.out.println();
}
}

输出结果:

1
2
fly
fly cost time is:115

我们可以这样理解,如上的动态代理实现实际是双层的静态代理,开发者提供了委托类 Bird(就是被代理的对象),程序动态生成了代理类Flyable。开发者还需要提供一个实现了InvocationHandler的子类TimingInvocationHandler,TimingInvocationHandler是代理类Flyable的委托类,委托类Bird的代理类。用户直接调用代理类Flyable的对象,Flyable将调用转发给委托类TimingInvocationHandler,TimingInvocationHandler再将调用转发给它的委托类Bird。
关于更多动态代理的知识, 可以看看这几篇
公共技术点之 Java 动态代理
10分钟看懂动态代理设计模式
从一道面试题开始说起 枚举、动态代理的原理
OK, 理解了动态代理之后, 我们可以看看Retrofit.create()这个方法了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public <T> T create(final Class<T> service) {
// 确保service这个类是一个接口, 并且这个接口没有实现别的接口
Utils.validateServiceInterface(service);
// 是否需要提前解析接口方法
if (validateEagerly) {
eagerlyValidateMethods(service);
}
// 传入类加载器, 接口对象, 和一个InvocationHandler
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 {
// If the method is a method from Object then defer to normal invocation.
// 返回表示声明由此Method对象表示的方法的类的Class对象
// 假如这个方法是从Object类继承下来的, 就调用InvocationHandler对象的方法
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
// 将接口方法构造为ServiceMethod, 注意这里是核心方法
ServiceMethod<Object, Object> serviceMethod =
(ServiceMethod<Object, Object>) loadServiceMethod(method);
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);
}
});
}

注释我已经在代码中写好了
重点就是这三句代码

1
2
3
ServiceMethod<Object, Object> serviceMethod = (ServiceMethod<Object, Object>) loadServiceMethod(method);
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);

我们来看看核心方法
先看这个

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
ServiceMethod<?, ?> loadServiceMethod(Method method) {
// 先从缓存中取ServiceMethod, 如果有的话
ServiceMethod<?, ?> result = serviceMethodCache.get(method);
if (result != null) return result;
// 如果没有缓存
synchronized (serviceMethodCache) {
// 再取一遍缓存, 如果还是没有, 就构造一个, 同时放到缓存里面
result = serviceMethodCache.get(method);
if (result == null) {
result = new ServiceMethod.Builder<>(this, method).build();
serviceMethodCache.put(method, result);
}
}
return result;
}

我们看看这个ServiceMethod是怎么构建出来的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
Builder(Retrofit retrofit, Method method) {
this.retrofit = retrofit;
// 接口的方法
this.method = method;
// 接口方法的注解
this.methodAnnotations = method.getAnnotations();
// 接口方法的参数类型
this.parameterTypes = method.getGenericParameterTypes();
// 接口方法的参数的注解
this.parameterAnnotationsArray = method.getParameterAnnotations();
}

public ServiceMethod build() {
// 根据方法的返回类型和方法的注解创建一个CallAdapter
// 如果没有添加 CallAdapter 那么默认会用 ExecutorCallAdapterFactory
callAdapter = createCallAdapter();
// response的类型, 其实就是方法的返回类型中的第一个泛型参数
// 比如 Call<User> 中的 User
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?");
}
// 根据responseType和方法的注解, 获取converterFactories中的第一个responseConverter
responseConverter = createResponseConverter();

// 根据接口方法的注解构造请求方法,比如 @GET @POST @DELETE 等
// 检查url中有无带?,转化 path 中的参数
// 另外如果有@Headers还有添加请求头,
for (Annotation annotation : methodAnnotations) {
parseMethodAnnotation(annotation);
}

if (httpMethod == null) {
throw methodError("HTTP method annotation is required (e.g., @GET, @POST, etc.).");
}

// 如果没有body, 就不能是Multipart和FormEncoded类型
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).");
}
}

// 下面的代码主要用来解析接口方法参数中的注解,比如 @Path @Query @QueryMap @Field 等等
// 相应的,每个方法的参数都创建了一个 ParameterHandler<?> 对象
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);
}

这两个方法主要就是对API接口中的方法进行解析, 构造一个ServiceMethod, 然后返回给OkHttpCall使用.大致做了这些事情:

  1. 创建CallAdapter
  2. 创建ResponseConerter
  3. 根据API接口方法的注解构造网络请求方法
  4. 根据API接口方法参数中的注解构造网络请求的参数
  5. 检查有无异常
    接下来看看OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);这个方法
    OkHttpCall的构造方法是这样的, 没什么可说
1
2
3
4
OkHttpCall(ServiceMethod<T, ?> serviceMethod, @Nullable Object[] args) {
this.serviceMethod = serviceMethod;
this.args = args;
}

接着再看return serviceMethod.callAdapter.adapt(okHttpCall);这个方法
这个serviceMethod.callAdapter就是serviceMethod在构建的时候创建出来的callAdapter, 跟踪createCallAdapter()这个方法, 在 Retrofit 中默认的 callAdapterFactory 是 ExecutorCallAdapterFactory, 所以这个callAdapter是由一个ExecutorCallAdapterFactory(来自于retrofitadapterFactories)get(Type returnType, Annotation[] annotations, Retrofit retrofit)生成的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
final class ExecutorCallAdapterFactory extends CallAdapter.Factory {
final Executor callbackExecutor;

ExecutorCallAdapterFactory(Executor callbackExecutor) {
this.callbackExecutor = callbackExecutor;
}

@Override
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<Object, Call<?>>() {
@Override public Type responseType() {
return responseType;
}

@Override public Call<Object> adapt(Call<Object> call) {
return new ExecutorCallbackCall<>(callbackExecutor, call);
}
};
}

可以看到这个get()方法返回了一个匿名内部类, 它的adpter方式是return new ExecutorCallbackCall<>(callbackExecutor, call);
看一下这个构造方法

1
2
3
4
5
6
7
8
9
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;
}
...

ExecutorCallbackCall实现了Retrofit.Call接口, 而我们看到OkHttpCall也是实现了Retrofit.Call接口的, 这个接口中的方法有execute(), enqueue(), isExecuted(), cancel(), isCanceled(), clone(), request()一共7个, 这里使用装饰者模式, 所以我们不妨将代码改写成这样更清楚一些

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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, @Nullable 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<Object, Object> serviceMethod =
(ServiceMethod<Object, Object>) loadServiceMethod(method);
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
return new ExecutorCallbackCall<>(callbackExecutor, okHttpCall);
// return serviceMethod.callAdapter.adapt(okHttpCall);
}
});
}

serviceMethod中包含了从create()方法中传入的接口字节码文件的所有方法, url, CallFactory, ResponseConverter等, 然后又把这个serviceMethod传入了OkHttpCall构造了一个okhttpCall对象, 然后又把这个okhttpCall对象传入了ExecutorCallbackCall构造了一个ExecutorCallbackCall对象.根据上面动态代理的知识, retrofit.create()会返回一个接口的对象, 调用这个接口对象的方法会调用InvocationHandler中的invoke方法, 返回值也是invoke方法的返回值, 而invoke方法的返回值是一个ExecutorCallbackCall对象, 一般我们都使用Retrofit.Call类型的变量来引用retrofit.create()返回的对象(因为接口中的方法的返回类型是Call嘛), 而正好ExecutorCallbackCall是实现了Retrofit.Call的, 所以这里不会有问题.同时ExecutorCallbackCall使用了装饰者模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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) {
checkNotNull(callback, "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);
}
});
}
});
}

@Override public boolean isExecuted() {
return delegate.isExecuted();
}
...

从上面的代码可以看到很显然这是装饰者模式, 对OkHttpCall的方法进行了包装.在retrofit.create()得到一个Call对象之后, 调用这个Call对象的enqueue()方法实际上是调用一个ExecutorCallbackCall对象的enqueue()方法, 不信可以将这个Call对象的名字打印一下

而ExecutorCallbackCall对象的enqueue()方法其实又是调用了传入进去的Retrofit2.OkHttpCall对象的enqueue()方法

ExecutorCallbackCall.execute()

接下来我们看看ExecutorCallbackCall.execute()吧, 异步的一会儿再看.

1
2
3
@Override public Response<T> execute() throws IOException {
return delegate.execute();
}

刚才说了, 这里的delegate其实是Retrofit.create()方法里传进来的OkHttpCall对象, 所以我们去看看

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
@Override public Response<T> execute() throws IOException {
okhttp3.Call call;

synchronized (this) {
if (executed) throw new IllegalStateException("Already executed.");
executed = true;

if (creationFailure != null) {
if (creationFailure instanceof IOException) {
throw (IOException) creationFailure;
} else {
throw (RuntimeException) creationFailure;
}
}

call = rawCall;
if (call == null) {
try {
// 注意这里的createRawCall()方法
call = rawCall = createRawCall();
} catch (IOException | RuntimeException e) {
creationFailure = e;
throw e;
}
}
}

if (canceled) {
call.cancel();
}

return parseResponse(call.execute());
}

注意一下注释中标记的createRawCall()方法, 我们跟踪一下

1
2
3
4
5
6
7
8
9
10
private okhttp3.Call createRawCall() throws IOException {
// 根据OkhttpCall$args构造一个okHttp的request
Request request = serviceMethod.toRequest(args);
// 这里的serviceMethod.callFactory其实是一个OkHttpClient对象
okhttp3.Call call = serviceMethod.callFactory.newCall(request);
if (call == null) {
throw new NullPointerException("Call.Factory returned null.");
}
return call;
}

可以看到这里其实返回的是一个okhttp3.Call对象, 然后在execute()方法里调用parseResponse(call.execute())方法将结果返回, 我们去看看这个方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
Response<T> 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();
// 根据code返回response错误
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();
}
}

// 根据code返回成功, 但是没有body
if (code == 204 || code == 205) {
rawBody.close();
return Response.success(null, rawResponse);
}

ExceptionCatchingRequestBody catchingBody = new ExceptionCatchingRequestBody(rawBody);
try {
// 利用serviceMethod中的responseConverter将body转换成泛型对象, 然后返回成功
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;
}
}

必要的注释我已经写了, 再看一下serviceMethod.toResponse(catchingBody);方法

1
2
3
4
/** Builds a method return value from an HTTP response body. */
R toResponse(ResponseBody body) throws IOException {
return responseConverter.convert(body);
}

那个这个responseConverter是在哪里赋值的呢?赋进去的是一个什么呢?
其实是在retrofit对象创建的时候, 在Retrofit.Builder的构造方法里

1
2
3
4
5
6
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());
}

可以看到加入了一个即使没有指定, 也加入了一个BuildInConverters, 里面包含了多种converter, 而serviceMethod里面的converter是在ServiceMethod的这里生成的

1
2
3
4
5
6
7
8
9
10
11
12
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();
...
}

具体的细节我就不细究了, 有时间再研究.总之用的是BuildInConverters中的responseBodyConverter()方法得到的Converter.看一下代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
final class BuiltInConverters extends Converter.Factory {
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
if (type == ResponseBody.class) {
return Utils.isAnnotationPresent(annotations, Streaming.class)
? StreamingResponseBodyConverter.INSTANCE
: BufferingResponseBodyConverter.INSTANCE;
}
if (type == Void.class) {
return VoidResponseBodyConverter.INSTANCE;
}
return null;
}

异步请求

关于异步请求, 我不想说的太多, 只说一下如何将okhttp中子线程的请求结果回调到主线程, 就贴几张图吧

注意到这个callbackExecutor, 又是从这里传进来

在这里被调用

而其实这里的platform是Android

总结

Retrofit的源码用到了不少设计模式, 外观模式,动态代理,策略模式,观察者模式, 简单点的还有 Builder 模式,工厂等.
CallAdapterFactory决定了interface中请求方法的返回类型, 比如默认是Call类型, 如果是RxJavaCallAdapterFactory就能返回Observable类型, 而ConverterFactory决定了返回类型的泛型, 比如这么一个interface

1
2
3
4
5
6
7
public interface GankApi {

// http://gank.io/api/data/福利/10/1
@GET("api/data/福利/{pagesize}/{page}")
Call<MeizhiModel> getMeiZhi(@Path("pagesize") int pageSize, @Path("page") int page);

}

Call类型还是Observable类型由CallAdapterFactory决定.
默认的ConverterFactory只能返回ResponseBody类型, 而加了GsonConverterFactory之后就能返回POJO类型, 也就是MeizhiModel类型.
关于这几点, 推荐怪盗kidou的这篇你真的会用 Retrofit2 吗? Retrofit2 完全教程, 写的十分的详细
关于retrofit, 还有许多的细节, 例如注解参数的校验, 拼接等等, 相信十分的繁琐, 不过我就先只写到这里了.

0%