这篇主要会走读一下Retrofit的源码,解析一下里面遇到的一些设计模式,网络请求的过程等。

开始

从创建Retrofit开始,看一下常见的创建Retrofit的实例的方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(interceptor)
.retryOnConnectionFailure(true)
.connectTimeout(15, TimeUnit.SECONDS)
.addNetworkInterceptor(createHeaderInterceptor())
.build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BuildConfig.BASE_API_URL)
.client(client)
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.addConverterFactory(BolomeGsonConverterFactory.create())
.build();
Net net = retrofit.create(Net.class)

从上面的代码可以看出,Retrofit并没有去真正的执行网络请求,还是交给了OkHttp来进行实现,Retrofit可以看作的对OkHttp的一层非常棒的封装,Retrofit的关注点是在如何让你更快捷更灵活的去进行网络请求。如果你使用过Retrofit的话,你也会明白用Retrofit去实现一次网络请求是多方便的事情。

retrofit.create

Net net = retrofit.create(Net.class)这里开始入手,用过Retrofit的几乎都知道Retrofit是用了动态代理,动态代理说简单点就是动态的去生成接口的实现类,也可以在原始的结果返回前对参数或者结果进行修改,这个特性也使得一些Hook框架大量使用了动态代理,比如很著名的360的DroidPlugin。有点扯远了,还是去源码里面去看看:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public <T> T create(final Class<T> 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 {
...
ServiceMethod serviceMethod = loadServiceMethod(method);
OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);
}
});
}

这里省略了一下判断的逻辑,但是主要的就是最后的三行代码,从方法的签名来看,是传进来一个接口类,返回一个接口类型的实例,但是这个实例的具体实现类型是由serviceMethod.callAdapter.adapt方法动态决定了,而且这个接口里面的每一次方法调用,都会进入这个invoke方法,也就是由接口的实现类去完成功能。例如,Retrofit默认的请求方式是Call<T>,这里默认的实现类就是ExecutorCallbackCall<T> implements Call<T>,而在这个类里面又是用代理类的方式去交给Okhttpcall去执行真正的请求,这个就是后面再说了。

ServiceMethod

这个类主要是储存了请求的信息和Retrofit的配置信息以及对请求注解的解析生成正常的地址和请求。

OkHttpCall

第二行OkHttpCall可以看成是OkHttpcallRetrofit层面的一次封装。从上面一步看到,把请求参数和配置信息交给了这个OkHttpCall,然后让OkHttp去执行请求操作。

callAdapter

不知道该怎么去具体描述这个类的意思,可以理解成将请求转换成不同的请求形式,例如默认的call或者常见的RxjavaObservable<T>的形式亦或者是AgeraSupplier<Result<T>>的形式等等。以@drakeetretrofit-agera-call-adapter为例:

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
public final class AgeraCallAdapterFactory extends CallAdapter.Factory {
public static AgeraCallAdapterFactory create() {
return new AgeraCallAdapterFactory();
}
private AgeraCallAdapterFactory() {
}
@Override
public CallAdapter<?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
...
支持Supplier<Result<T>>形式
return new BodyCallAdapter(innerTypeOfInnerType);
}
...支持Supplier<Result<Response<T>>>形式
return new ResponseCallAdapter(responseType);
}
private static class BodyCallAdapter implements CallAdapter<Supplier<?>> {
private final Type responseType;
BodyCallAdapter(Type responseType) {
this.responseType = responseType;
}
@Override public Type responseType() {
return responseType;
}
@Override
public <T> Supplier<Result<T>> adapt(Call<T> call) {
return new CallSupplier(call);
}
}
}
class CallSupplier<T> implements Supplier<Result<T>> {
private final Call<T> originalCall;
CallSupplier(@NonNull final Call<T> call) {
this.originalCall = checkNotNull(call);
}
@NonNull @Override public Result<T> get() {
Result<T> result;
try {
Response<T> response = originalCall.clone().execute();
//将Response转换成Result<T>的形式 因为数据要从Result中取,而不像默认的call那样直接走回调
if (response.isSuccessful()) {
result = Result.success(response.body());
} else {
result = Result.failure(new HttpException(response));
}
} catch (IOException e) {
e.printStackTrace();
result = Result.failure(e);
}
return result;
}
}

代码没太多难度,看看就明白了。也是非常棒的自定义CallAdapter教程。

enqueue

异步请求的时候是这个样子的

1
2
3
4
5
6
7
8
9
10
11
mNet.getLiveShows(20, 1).enqueue(new Callback<LiveBlock>() {
@Override
public void onResponse(Call<LiveBlock> call, Response<LiveBlock> response) {
}
@Override
public void onFailure(Call<LiveBlock> call, Throwable t) {
}
});

getLiveShows返回的call其实是上面说的ExecutorCallbackCall,这个的enqueue是这样的

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

调用了delegate.enqueue这个delegate就是上面说到的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
34
35
36
37
38
39
40
41
42
43
call.enqueue(new okhttp3.Callback() {
@Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse)
throws IOException {
Response<T> response;
try {
response = parseResponse(rawResponse);
} catch (Throwable e) {
callFailure(e);
return;
}
callSuccess(response);
}
@Override public void onFailure(okhttp3.Call call, IOException e) {
try {
callback.onFailure(OkHttpCall.this, e);
} catch (Throwable t) {
t.printStackTrace();
}
}
private void callFailure(Throwable e) {
try {
callback.onFailure(OkHttpCall.this, e);
} catch (Throwable t) {
t.printStackTrace();
}
}
private void callSuccess(Response<T> response) {
try {
callback.onResponse(OkHttpCall.this, response);
} catch (Throwable t) {
t.printStackTrace();
}
}
Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
ResponseBody rawBody = rawResponse.body();
.....//使用responseConverter.convert(body)
T body = serviceMethod.toResponse(catchingBody);
return Response.success(body, rawResponse);
....
}

注意的是这里几个call的区别和三个enqueue的区别和作用

###Converter
这个是用来将RequestBodyresponseBody转换成相应的类型,具体去看看官方的GsonConverterFactory就可以了