Retrofit源码分析

Retrofit源码分析

Retrofit的亮点

先来看一个最基本的Retrofit+Gson的用法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// https://raw.githubusercontent.com/xiaoniaojun/xiaoniaojun.github.io/master/test.json
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://raw.githubusercontent.com/")
.addConverterFactory(GsonConverterFactory.create())
.build();
GitHub gitHub = retrofit.create(GitHub.class);
Call<User> xiaoniaojun = gitHub.results("xiaoniaojun", "test.json");
xiaoniaojun.enqueue(new Callback<User>() {
@Override
public void onResponse(Call<User> call, Response<User> response) {
User responseUser = response.body();
}
 
@Override
public void onFailure(Call<User> call, Throwable t) {
t.printStackTrace();
}

Retrofit让我们可以使用注解接口方法的方式来实现解析Url,构造一个可执行对象,这个可执行对象可以直接调用网络请求的操作并对返回结果进行同步/异步处理。其中最亮的地方是,这个可执行对象既可以是一个在java8或者Android平台可以直接调用的Call对象,也可以是一个Observer对象。并且,对于返回的response,可以加入Converter来将其内容以特定的方式解析,比如请求json对象,可以使用GsonConverter来将response body直接解析为具体的对象,又或者是可以自定义如何包装request。

public Retrofit build()方法:

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
/**
* 根据设置的配置值来创建{@link Retrofit}实例
* <p>
* 注意: 如果{@link #client}和{@link #callFactory} 都没有被调用,就默认生成和使用{@link
* OkHttpClient}。
*/
public Retrofit build() {
// 如果不提供baseUrl,就会抛出异常。
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
// 这个callFactroy是一个空的值,所以这句代码没有任何作用,估计是遗留代码。
okhttp3.Call.Factory callFactory = this.callFactory;
// 默认使用OkHttpClient来创建CallFactory
// Factory是一个接口,内部只有一个newCall(Request r)方法。
if (callFactory == null) {
callFactory = new OkHttpClient();
}
 
// 这里的CallbackExecutor,是封装了主线程Looper的Handler,
// 所以这个默认的CallbackExecutor会将回调在主线程中执行。
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
 
// 防御性拷贝adapters,并添加默认Call adapter。
// 1.解析defaultCallAdapterFactory
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);
}

这个装配的过程其实就是在为Retrofit配置几个关键组件:
我们先列出它们,再来一个一个分析。
baseUrl: 基url地址,在它上面构建完整的url请求,这个没什么好解释的。
callFactory:
call工厂,call是干嘛的?是我们最终用来执行http请求和接受的。
下面我们再来剖析这个东西。
callbackExecutor:
回调执行者,这个是用来执行回调的。为什么要封装它?因为它是用来控制执行线程的。
adapterFactories:
适配器工厂,适配的什么?
converterFactories
转换器工厂,转换的什么?

CallFactory

首先,这个callFactory是由以下代码生成的:

1
callFactory = new OkHttpClient();

这条语句创建的。我们知道,Retrofit的网络请求是基于OkHttp实现的,那这里很明显是实际执行网络操作的请求的方法。
我们跟进去OkHttpClient类,

1
public class OkHttpClient implements Cloneable, Call.Factory, WebSocket.Factory

由于这里OkHttpClient行使的是Factory的职责,我们主要看OkHttpClient实现的这个接口的方法。
Call.Factory只有一个方法:

1
2
3
@Override public Call newCall(Request request) {
return new RealCall(this, request, false /* for web socket */);
}

传递进一个request对象,把它转换成可执行的Call对象。

到这里,callFactory就具备了它的职责,根据request来构建Call。

现在我们来审查一下这个OkHttpClient对象。
它具备的能力有:执行各种网络操作、将这些操作构建成Call对象。

这里我们再谈谈Call接口。

request返回初始化这个call的原生request对象,
其余都是控制请求执行的指令。

然后,这个RealCall是Call接口的实现类,它实际处理对OkHttp的调用。
由于我们这里只分析Retrofit,所以这个部分我们就省略了。现在只需要知道,
通过CallFactory,我们可以构建Call对象,而这个Call就是在执行网络请求。

CallbackExecutor

同样来看一下生成CallbackExecutor实例的方法,

1
callbackExecutor = platform.defaultCallbackExecutor();

首先这个CallbackExecutor是一个Executor类型对象。Executor是java并发包中的接口,
只有一个execute方法,就是用来执行Runnable的。这个是用来解耦的。


Platform工具类提供了多平台支持。它在初始化的时候调用其findPlatform方法查看调用环境。
在Andoird平台上,提供了MainThreadExecutor用来在主线程中执行代码。
那么这个CallbackExecutor是干什么的呢?看名字就知道,是用于执行回调的。
网络请求返回response,接收处理的结果很多时候是需要在主线程中更新ui的。

1
2
3
@Override public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}

所以最终在Andoird平台上,默认的CallbackExecutor是这个MainThreadExecutor
,也就是说,回调默认是在主线程中执行的。

adapterFactory

1
2
List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);
adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));

接下来又是一个平台相关的CallAdapterFactory。
在Android平台中,默认的defaultCallAdapterFactory是ExecutorCallAdapterFactory。

1
2
3
@Override CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {
return new ExecutorCallAdapterFactory(callbackExecutor);
}


这个CallAdapter到底适配的是什么?
答案就是,我们在定义那个创建链接的接口时,不是声明了一个Call吗,这个Adapter就是将我们的CallFactory产生的Call与CallbackExecutor融合起来,创建一个生产Call对象的工厂。注意CallAdapter接口里面的那个adapter方法,就是做这件事的。

1. CallAdapterFactory

1
2
3
4
5
6
7
8
CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {
// 如果callbackExecutor不为空,则调用ExecutorCallAdapterFactory(callbackExecutor)
if (callbackExecutor != null) {
return new ExecutorCallAdapterFactory(callbackExecutor);
}
// 否则返回默认的CallAdapterFactory
return DefaultCallAdapterFactory.INSTANCE;
}
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
final class ExecutorCallAdapterFactory extends CallAdapter.Factory {
final Executor callbackExecutor;
#
ExecutorCallAdapterFactory(Executor callbackExecutor) {
this.callbackExecutor = callbackExecutor;
}
// 这个方法传入的参数有
// returnType,返回类型
// annotations,注解
// retrofit
// 从这些参数我们可以推断,这个CallAdapter是将之前所有的请求设置封装到Call中的关键
@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);
}
};
}

##Retrofit构造函数

1
2
3
4
5
6
7
8
9
10
Retrofit(okhttp3.Call.Factory callFactory, HttpUrl baseUrl,
List<Converter.Factory> converterFactories, List<CallAdapter.Factory> adapterFactories,
Executor callbackExecutor, boolean validateEagerly) {
this.callFactory = callFactory;
this.baseUrl = baseUrl;
this.converterFactories = unmodifiableList(converterFactories); // Defensive copy at call site.
this.adapterFactories = unmodifiableList(adapterFactories); // Defensive copy at call site.
this.callbackExecutor = callbackExecutor;
this.validateEagerly = validateEagerly;
}

在构造方法中,将工厂中设置的所有配置变量进行初始化赋值。

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, 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);
}
});
}
1
2
3
4
5
6
7
8
9
10
11
12
class Plathform {
private static final Platform PLATFORM = findPlatform();
// getter
static Platform get();
// 这个方法查看当前代码运行平台(java8 Android 等等)
private static Platform findPlatform();
}
// 默认回调Executor为null
Executor defaultCallbackExecutor() {return null};
CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {
 
}

动态代理的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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 {
 
// 如果是Object声明的方法就直接调用。
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
// 垃圾代码,已经弃用
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
// 这里是在处理Retrofit注解
ServiceMethod<Object, Object> serviceMethod =
(ServiceMethod<Object, Object>) loadServiceMethod(method);
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);
}
});
 
坚持原创技术分享,您的支持将鼓励我继续创作!
posted @ 2017-08-09 17:14  天涯海角路  阅读(158)  评论(0)    收藏  举报