Hiten's Blog.

retrofit2.0源码解析(一)

字数统计: 2.7k阅读时长: 13 min
2016/08/01 Share

题外话

第一次听说retrofit框架,还是同窗hanks推荐,SOHO的大字依旧发着光,hanks早已不在望京上班,hanks的github

Retrofit,一个类型安全的http客户端,适用于Android和Java

分析源码之前,首先在github上download源码,用IDEA打开编译。

先看一段官方提供的示例代码

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
//定义一个实体类
public static class Contributor {
public final String login;
public final int contributions;
public Contributor(String login, int contributions) {
this.login = login;
this.contributions = contributions;
}
}

//定义一个API接口
public interface GitHub {
@GET("/repos/{owner}/{repo}/contributors")
Call<List<Contributor>> contributors(
@Path("owner") String owner,
@Path("repo") String repo);
}
//创建retrofit对象
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(API_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();

// 创建 GitHub 对象.
GitHub github = retrofit.create(GitHub.class);

//请求contributors方法
Call<List<Contributor>> call = github.contributors("square", "retrofit");

//得到结果
List<Contributor> contributors = call.execute().body();
//打印结果
for (Contributor contributor : contributors) {
System.out.println(contributor.login + " (" + contributor.contributions + ")");
}

就这样,一个简单的Http请求就完成了,下面顺着流程,分析一下

Retrofit对象创建流程

Retrofit对象创建采用了Build模式,下面来看看Builder的源码

Retrofit.Builder

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
//成员变量和构造
public static final class Builder {
//平台,主要有三个实现类
private Platform platform;

//OkHttp包下面的接口,OkHttpClient就实现了它,这里主要是设置client
private okhttp3.Call.Factory callFactory;

//OkHttp包下的Url包装类
private HttpUrl baseUrl;

//转换器工厂List,用户数据转对象,比如Gson,JackSon
private List<Converter.Factory> converterFactories = new ArrayList<>();

//用来请求和接受的Call适配器,比如说可拓展RXJava
private List<CallAdapter.Factory> adapterFactories = new ArrayList<>();

//callBack所在的线程,比如Android是在UI线程回调,这个默认在Platform的defaultCallbackExecutor方法提供
private Executor callbackExecutor;

//是否预加载所以方法对应的ServiceMethod
private boolean validateEagerly;


Builder(Platform platform) {
this.platform = platform;
//converterFactories的默认有一个元素,为BuiltInConverters对象
converterFactories.add(new BuiltInConverters());
}

//默认构造
public Builder() {
this(Platform.get());
}

}

再看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
public Retrofit build() {

//BaseUrl肯定不能为空
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}

//如果用户不设置callFactory,就在这里创建OkHttpClient对象,就在这里
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new OkHttpClient();
}
//如果用户不设置callbackExecutor,就取平台的callbackExecutor
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}

//新建一个新数组,拷贝原数组数据并添加一个默认数据
List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);
adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));

//同样是拷贝一份
List<Converter.Factory> converterFactories = new ArrayList<>(this.converterFactories);

//创建Retrofit对象
return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,
callbackExecutor, validateEagerly);
}

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
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

//传入一个泛型Class,返回该泛型示例
public <T> T create(final Class<T> service) {

//判断这个Class必须是接口,且不能有父接口
Utils.validateServiceInterface(service);

//预加载当前service对象所有method对应的ServiceMethod
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 {

//如果是一个Object默认的方法,由Object执行
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}

//如果是平台默认的方法,由该平台执行
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}

//将method封装成ServiceMethod对象,loadServiceMethod设计有缓存
ServiceMethod serviceMethod = loadServiceMethod(method);

//将serviceMethod和args封装成OkHttpCall对象
OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);

//由callAdapter对象的adapt方法执行okHttpCall,返回的就是接口申明的对象
return serviceMethod.callAdapter.adapt(okHttpCall);
}
});
}

//刷新method缓存
private void eagerlyValidateMethods(Class<?> service) {
Platform platform = Platform.get();
for (Method method : service.getDeclaredMethods()) {
if (!platform.isDefaultMethod(method)) {
loadServiceMethod(method);
}
}
}

//加载ServiceMethod
ServiceMethod loadServiceMethod(Method method) {
ServiceMethod result;

//serviceMethodCacheRetrofit成员,用来缓存method ServiceMethod键值
synchronized (serviceMethodCache) {
//去缓存
result = serviceMethodCache.get(method);
//缓存没有,创建,存起来
if (result == null) {
result = new ServiceMethod.Builder(this, method).build();
serviceMethodCache.put(method, result);
}
}
return result;
}

到了这里,Retrofit这个类的大致功能分析完了,梳理一下,Retrofit采用Build模式接受一堆配置参数构建,使用动态代理代理对象,这里发现几个比较关键的类,有
Platform,CallAdapter,Converter,ServiceMethod,OkHttpCall等
接下来,看来来这些类是怎么实现的

Platform类

Platform标识当前运行环境所处的平台,有三个子类Java8、Android、IOS,这里只对Platform和Android这两个类源码作分析

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
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) {
}
try {
Class.forName("org.robovm.apple.foundation.NSObject");
return new IOS();
} catch (ClassNotFoundException ignored) {
}
return new Platform();
}

//默认的回调Executor
Executor defaultCallbackExecutor() {
return null;
}

//默认CallAdapterFactory
CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {
if (callbackExecutor != null) {
return new ExecutorCallAdapterFactory(callbackExecutor);
}
return DefaultCallAdapterFactory.INSTANCE;
}

//是否是默认方法
boolean isDefaultMethod(Method method) {
return false;
}
//执行默认方法,没有默认方法
Object invokeDefaultMethod(Method method, Class<?> declaringClass, Object object, Object... args)
throws Throwable {
throw new UnsupportedOperationException();
}


//Android实现
static class Android extends Platform {

//主线程回调
@Override public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}

//默认CallAdapterFactory
@Override CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {
return new ExecutorCallAdapterFactory(callbackExecutor);
}

static class MainThreadExecutor implements Executor {
//创建Handler对象,设置主线程Looper对象
private final Handler handler = new Handler(Looper.getMainLooper());
@Override public void execute(Runnable r) {
//主线程执行任务
handler.post(r);
}
}
}

}

Platform类其实很简单,只做三件事,

  • 判断当前处于何种环境,返回对应的Platform
  • 创建回调Exector
  • 创建defaultCallAdapterFactory

ServiceMethod类

ServiceMethod的创建是在loadServiceMethod方法中可以看到, 就是这句代码:new ServiceMethod.Builder(this, method).build();
可以看出ServiceMethod也是Builder模式构造,我猜测ServiceMethod对应于method,是对method的封装,ServiceMethod类大多都是对注解进行
解析的,所以我打算拿到下一篇博客来讲。

Call接口

Call接口定义了一些同步,异步,取消,请求等方法,主要实现类是OkHttpCall
OkHttpCall在newProxyInstance方法中可以看到:OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);

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
86
87
88
89
90
91
92
93
94
95
96
97
98
99

final class OkHttpCall<T> implements Call<T> {

//ServiceMethod对象
private final ServiceMethod<T> serviceMethod;

//请求参数
private final Object[] args;

//是否已经取消
private volatile boolean canceled;

//构造方法
OkHttpCall(ServiceMethod<T> serviceMethod, Object[] args) {
this.serviceMethod = serviceMethod;
this.args = args;
}
//同步请求方法
@Override public Response<T> execute() throws IOException {

//OkHttp包里的call
okhttp3.Call call;

synchronized (this) {
//已经在执行,报异常
if (executed) throw new IllegalStateException("Already executed.");

//标记为已执行
executed = true;

//如果creationFailure不为空,报异常
if (creationFailure != null) {
if (creationFailure instanceof IOException) {
throw (IOException) creationFailure;
} else {
throw (RuntimeException) creationFailure;
}
}

call = rawCall;
if (call == null) {
try {
//创建OkHttp Call
call = rawCall = createRawCall();
} catch (IOException | RuntimeException e) {
creationFailure = e;
throw e;
}
}
}
//取消请求
if (canceled) {
call.cancel();
}
//执行请求,并解析
return parseResponse(call.execute());
}

//解析方法
Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
//得到Body
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();
}
}
//TTP 204(no content)表示响应执行成功,但没有数据返回,浏览器不用刷新,不用导向新页面。
//HTTP 205(reset content) 表示响应执行成功,重置页面(Form表单),方便用户下次输入。
if (code == 204 || code == 205) {
return Response.success(null, rawResponse);
}

ExceptionCatchingRequestBody catchingBody = new ExceptionCatchingRequestBody(rawBody);
try {
//Json解析
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;
}
}

}

OKHttpCall主要对OKHttp请求过程的封装,最终的Json解析也是在parseResponse方法中调用serviceMethod.toResponse方法执行;

CallAdapter接口和CallAdapter.Factory类

CallAdapter.Factory是为了生产CallAdapter示例而存在,源码如下

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 interface CallAdapter<T> {

//JSON解析后返回的格式,例如List<Contributor>
Type responseType();

//输入参数R为JSON数据映射出的类型,例如List<Contributor>,返回参数T为最终的类型,例如Call<List<Contributor>>
<R> T adapt(Call<R> call);

//工厂
abstract class Factory {

//创建CallAdapter对象,returnType为返回的格式比如Void或者Call<T>
public abstract CallAdapter<?> get(Type returnType, Annotation[] annotations,
Retrofit retrofit);

//根据数据参数获取其中第index个的type类型
protected static Type getParameterUpperBound(int index, ParameterizedType type) {
return Utils.getParameterUpperBound(index, type);
}

//获取元素数据类型,将Type转换成Class
protected static Class<?> getRawType(Type type) {
return Utils.getRawType(type);
}
}
}

从Platform的defaultCallAdapterFactory方法中看到两个CallAdapterFactory实现类ExecutorCallAdapterFactory和DefaultCallAdapterFactory,

DefaultCallAdapterFactory是一个单例,主要重写get方法

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 DefaultCallAdapterFactory extends CallAdapter.Factory {
static final CallAdapter.Factory INSTANCE = new DefaultCallAdapterFactory();

@Override
public CallAdapter<?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
if (getRawType(returnType) != Call.class) {
return null;
}
//从returnType中得出responseType
final Type responseType = Utils.getCallResponseType(returnType);
//创建一个新的Adapter类
return new CallAdapter<Call<?>>() {
@Override public Type responseType() {
return responseType;
}

@Override public <R> Call<R> adapt(Call<R> call) {
//直接返回,不做转换
return call;
}
};
}
}

ExecutorCallAdapterFactory主要是采用静态代理的方式,处理CallBack的线程调度

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
86
87
88
89
90
91
final class ExecutorCallAdapterFactory extends CallAdapter.Factory {
//callbackExecutor
final Executor callbackExecutor;

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

@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);
}
};
}

//代理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;
}

//代理enqueue方法
@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);
}
});
}
});
}

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

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

@Override public void cancel() {
delegate.cancel();
}

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

@SuppressWarnings("CloneDoesntCallSuperClone") // Performing deep clone.
@Override public Call<T> clone() {
return new ExecutorCallbackCall<>(callbackExecutor, delegate.clone());
}

@Override public Request request() {
return delegate.request();
}
}
}

CallAdapter和factory的深入理解,放到下一篇,这一篇主要是把大概串通的,期待下一篇博客。

CATALOG
  1. 1. Retrofit对象创建流程
    1. 1.1. Retrofit.Builder
  2. 2. create方法解析
  3. 3. Platform类
  4. 4. ServiceMethod类
  5. 5. Call接口
  6. 6. CallAdapter接口和CallAdapter.Factory类