技术沉思录

Android网络编程-Retrofit源码角度分析Http

字数统计: 5.1k阅读时长: 25 min
2019/07/25

上一篇讲解了OKHttp,本篇来介绍下它的黄金搭档Retrofit,OKHttp+Retrofit是网络框架的不二之选。同是Square出品,和OKHttp融合起来非常简单。
Retofit是一个RESTful的HTTP网络请求框架,有以下特点:

  • 基于OKHttp
  • 通过注解配置网络请求参数
  • 支持同步、异步请求
  • 支持多种序列化、反序列化格式
  • 解耦彻底、模块高度封装,使用很多设计模式来实现

基本使用

下面讲解的是官网的例子

创建网络请求接口

1
2
3
4
public interface GitHubService {
@GET("users/{user}/repos")
Call<List<Repo>> listRepos(@Path("user") String user);
}

创建Retrofit实例(使用建造者模式)

1
2
3
4
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.addConverterFactory(GsonConverterFactory.create())
.build();

创建网络接口实例

1
2
3
GitHubService service = retrofit.create(GitHubService.class);

Call<List<Repo>> repos = service.listRepos("yeungeek");

发送网络请求

默认返回的是OKHttpCall,实际真正发送请求的就是OKHttp

同步

1
Response<List<Repo>> list = repos.execute()

异步

1
2
3
4
5
6
7
8
9
call.enqueue(new Callback<List<Repo>>() {
@Override
public void onResponse(Call<List<Repo>> call, Response<List<Repo>> response) {
}

@Override
public void onFailure(Call<List<Repo>> call, Throwable t) {
}
});

请求流程

具体的请求流程可以分为7大步骤
retrofit

  1. 解析网络请求接口的注解,配置网络请求参数
  2. 通过动态代理生成网络请求对象
  3. 通过CallAdapter,将网络请求对象进行平台适配(Android,Java8)
  4. 通过网络请求执行器(Call),发送网络请求
  5. 通过Converter进行数据解析
  6. 通过回调执行器,进行线程切换
  7. 在主线程处理返回结果

Refrofit最大特点是使用了大量的设计模式,来进行解耦,下图是完整的流程图(来自Stay 在 Retrofit分析-漂亮的解耦套路):
retrofit 流程图
接下来通过源码分析,详细讲解上面的流程

源码分析

Retrofit初始化

1
2
3
4
5
6
Retrofit retrofit = new Retrofit  //1. Retrofit声明
.Builder() //2. Builder
.baseUrl("https://api.github.com/") //3. baseUrl
.addConverterFactory(GsonConverterFactory.create()) //4. Converter Factory
.addCallAdapterFactory(RxJava2CallAdapterFactory.create()) //5. CallAdapter Factory
.build(); //6. 生成实例

Retrofit声明

在使用Retrofit时,首先通过建造者模式构建Retrofit。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public final class Retrofit {
private final Map<Method, ServiceMethod<?, ?>> serviceMethodCache = new ConcurrentHashMap<>();

final okhttp3.Call.Factory callFactory;
final HttpUrl baseUrl;
final List<Converter.Factory> converterFactories;
final List<CallAdapter.Factory> callAdapterFactories;
final @Nullable Executor callbackExecutor;
final boolean validateEagerly;

Retrofit(okhttp3.Call.Factory callFactory, HttpUrl baseUrl,
List<Converter.Factory> converterFactories, List<CallAdapter.Factory> callAdapterFactories,
@Nullable Executor callbackExecutor, boolean validateEagerly) {
this.callFactory = callFactory;
this.baseUrl = baseUrl;
this.converterFactories = converterFactories; // Copy+unmodifiable at call site.
this.callAdapterFactories = callAdapterFactories; // Copy+unmodifiable at call site.
this.callbackExecutor = callbackExecutor;
this.validateEagerly = validateEagerly;
}
......
}
  • serviceMethodCache:网络请求配置对象缓存,通过解析网络请求接口后得到请求对象
  • callFactory:网络请求器工厂(Call),默认实现是OKHttp
  • baseUrl:网络请求Url地址
  • converterFactories:数据转换器工厂集合
  • callAdapterFactories:请求适配器工厂集合
  • callbackExecutor:回调方法执行器
  • validateEagerly:是否提前验证请求方法

剩下的步骤都是来初始化上面的参数

Builder

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public static final class Builder {
private final Platform platform;
private @Nullable okhttp3.Call.Factory callFactory;
private HttpUrl baseUrl;
private final List<Converter.Factory> converterFactories = new ArrayList<>();
private final List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>();
private @Nullable Executor callbackExecutor;
private boolean validateEagerly;

Builder(Platform platform) {
this.platform = platform;
}

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

Builder中的参数和 Retrfit 是意义一一对应的,默认构造函数进行平台的选择

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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();
}
......
}

通过反射来判断选择Android还是Java8,以前版本还有对IOS平台的支持,最新版本已经去掉了。
我们看下Android平台:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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();
//默认的 CallAdapter
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);
}
}
}

baseUrl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public Builder baseUrl(String baseUrl) {
checkNotNull(baseUrl, "baseUrl == null");
HttpUrl httpUrl = HttpUrl.parse(baseUrl);
if (httpUrl == null) {
throw new IllegalArgumentException("Illegal URL: " + baseUrl);
}
return baseUrl(httpUrl);
}
......
public Builder baseUrl(HttpUrl baseUrl) {
checkNotNull(baseUrl, "baseUrl == null");
List<String> pathSegments = baseUrl.pathSegments();
//检查合法性
if (!"".equals(pathSegments.get(pathSegments.size() - 1))) {
throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl);
}
this.baseUrl = baseUrl;
return this;
}

把String url 转换成HttpUrl,会对baseUrl进行合法性校验(URL参数是不是以”/“结尾)

ConverterFactory

1
2
3
4
public Builder addConverterFactory(Converter.Factory factory) {
converterFactories.add(checkNotNull(factory, "factory == null"));
return this;
}

把factory加到数据转换器集合中,看下GsonFactory.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
public static GsonConverterFactory create(Gson gson) {
if (gson == null) throw new NullPointerException("gson == null");
return new GsonConverterFactory(gson);
}

private final Gson gson;

private GsonConverterFactory(Gson gson) {
this.gson = gson;
}

@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
return new GsonResponseBodyConverter<>(gson, adapter);
}

@Override
public Converter<?, RequestBody> requestBodyConverter(Type type,
Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
return new GsonRequestBodyConverter<>(gson, adapter);
}

GsonConverterFactory使用Gson 为初始化参数,实现responseBodyConverterrequestBodyConverter接口,进行真正的数据转换处理。

CallAdapterFactory

1
2
3
4
public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
callAdapterFactories.add(checkNotNull(factory, "factory == null"));
return this;
}

把factory加到请求适配器工厂集合中,Android 平台默认实现是ExecutorCallAdapterFactory,后面再进行详细讲解。

build

最后一步build生成Retrofit对象

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 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> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
callAdapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));

// Make a defensive copy of the converters.
List<Converter.Factory> converterFactories =
new ArrayList<>(1 + this.converterFactories.size());

// 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());
converterFactories.addAll(this.converterFactories);

return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
}
  • callFactory配置,默认OkHttpClient
  • callbackExecutor配置,Android 平台默认使用MainThreadExecutor
  • callAdapterFactories配置,先加入自定义的callAdapter,然后再加入defaultCallAdapterFactory
  • converterFactories配置,先加入内建转换器(BuiltInConverters),然后加入自定义的数据转换器
  • 生成Retrofit对象

创建网络接口实例

1
2
3
4
5
6
7
8
public interface GitHubService {
@GET("users/{user}/repos")
Call<List<Repo>> listRepos(@Path("user") String user);
}
//创建接口实例
GitHubService service = retrofit.create(GitHubService.class);
//生成请求对象
Call<List<Repo>> repos = service.listRepos("yeungeek");

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
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.adapt(okHttpCall);
}
});
}

create方法中最重要的是使用了动态代理,调用接口的方法都会到Proxy的invoke方法中,在invoke方法中最重要的就是下面三行代码

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

loadServiceMethod

该方法读取网络请求接口里的方法,根据配置生成ServiceMethod对象

1
2
3
4
5
6
7
8
9
10
11
12
ServiceMethod<?, ?> loadServiceMethod(Method method) {
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;
}

loadServiceMethod会先从cache中获取对象,如果获取不到,则通过建造者模式生成ServiceMethod对象。

1
new ServiceMethod.Builder<>(this, method).build();

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
final class ServiceMethod<R, T> {
// Upper and lower characters, digits, underscores, and hyphens, starting with a character.
static final String PARAM = "[a-zA-Z][a-zA-Z0-9_-]*";
static final Pattern PARAM_URL_REGEX = Pattern.compile("\\{(" + PARAM + ")\\}");
static final Pattern PARAM_NAME_REGEX = Pattern.compile(PARAM);

private final okhttp3.Call.Factory callFactory;
private final CallAdapter<R, T> callAdapter;

private final HttpUrl baseUrl;
private final Converter<ResponseBody, R> responseConverter;
private final String httpMethod;
private final String relativeUrl;
private final Headers headers;
private final MediaType contentType;
private final boolean hasBody;
private final boolean isFormEncoded;
private final boolean isMultipart;
private final ParameterHandler<?>[] parameterHandlers;

ServiceMethod(Builder<R, T> builder) {
this.callFactory = builder.retrofit.callFactory();
this.callAdapter = builder.callAdapter;
this.baseUrl = builder.retrofit.baseUrl();
this.responseConverter = builder.responseConverter;
this.httpMethod = builder.httpMethod;
this.relativeUrl = builder.relativeUrl;
this.headers = builder.headers;
this.contentType = builder.contentType;
this.hasBody = builder.hasBody;
this.isFormEncoded = builder.isFormEncoded;
this.isMultipart = builder.isMultipart;
this.parameterHandlers = builder.parameterHandlers;
}
......
}
  • callFactory:网络请求器工厂,和retrofit对象声明中的含义一样
  • callAdapter:网络请求适配器工厂
  • baseUrl:网络请求Url地址
  • responseConverter:Response 数据转换器
  • httpMethod:http 请求方法
  • relativeUrl:网络请求相对地址
  • headers:网络请求头
  • contentType:网络请求 body 类型
  • parameterHandlers:方法处理解析器

ServiceMethod.Builder

1
2
3
4
5
6
7
Builder(Retrofit retrofit, Method method) {
this.retrofit = retrofit;
this.method = method;
this.methodAnnotations = method.getAnnotations();
this.parameterTypes = method.getGenericParameterTypes();
this.parameterAnnotationsArray = method.getParameterAnnotations();
}
  • methodAnnotations:网络请求接口方法注解
  • parameterTypes:网络请求接口方法里的参数注解
  • parameterAnnotationsArray:网络请求接口方法里的注解内容

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
public ServiceMethod build() {
//1. 从 Retrofit 中获取网络请求器
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?");
}
//2. 从 Refrofit 中获取数据转换器
responseConverter = createResponseConverter();
for (Annotation annotation : methodAnnotations) {
//3. 解析网络请求接口中方法的注解
parseMethodAnnotation(annotation);
}
.....
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.");
}

//4. 创建ParameterHandler<?>,用来解析来解析参数使用到注解
parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);
}
......
return new ServiceMethod<>(this);
}

createCallAdapter:根据接口方法返回类型、接口请求的注解,获取网络请求器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
private CallAdapter<T, R> 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 {
//noinspection unchecked
return (CallAdapter<T, R>) 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);
}
}

createResponseConverter:根据接口请求注解类型、返回类型,获取数据数据转换器

1
2
3
4
5
6
7
8
9
10
private Converter<ResponseBody, T> createResponseConverter() {
//获取接口请求的注解
Annotation[] annotations = method.getAnnotations();
try {
//从Rtrofit中获取数据转换器
return retrofit.responseBodyConverter(responseType, annotations);
} catch (RuntimeException e) { // Wide exception range because factories are user code.
throw methodError(e, "Unable to create converter for %s", responseType);
}
}

parseMethodAnnotation:解析请求接口的方法注解,主要有以下标签

  • Http请求方法
  • Headers
  • Multipart
  • FormUrlEncoded

parseParameter:对方法的参数注解进行解析
包含:Url,Path,Query,QueryName,QueryMap,Header,HeaderMap,Field,FieldMap,Part,PartMap,Body

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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;
}

OKHttpCall

根据serviceMethod和请求参数,创建OkHttpCall对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
final class OkHttpCall<T> implements Call<T> {
private final ServiceMethod<T, ?> serviceMethod;
private final @Nullable Object[] args;

private volatile boolean canceled;

@GuardedBy("this")
private @Nullable okhttp3.Call rawCall;
@GuardedBy("this") // Either a RuntimeException, non-fatal Error, or IOException.
private @Nullable Throwable creationFailure;
@GuardedBy("this")
private boolean executed;

OkHttpCall(ServiceMethod<T, ?> serviceMethod, @Nullable Object[] args) {
this.serviceMethod = serviceMethod;
this.args = args;
}
......
}

serviceMethod和 args不做介绍了

  • rawCall:OKHttp,真正发送网络请求
  • canceled:取消请求标志位
  • executed:是否执行标志位
  • creationFailure:异常标志位

adapt

根据ServiceMethod的中的callAdapter,来真正执行adapt方法
ServiceMethod的adapt方法

1
2
3
T adapt(Call<R> call) {
return callAdapter.adapt(call);
}

Android 默认的返回 ExecutorCallAdapterFactory的Call
这里使用了静态代理delegate,加入一些额外的操作

1
2
3
4
5
6
7
8
public Call<Object> adapt(Call<Object> call) {
return new ExecutorCallAdapterFactory.ExecutorCallbackCall(ExecutorCallAdapterFactory.this.callbackExecutor, call);
}
......
ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) {
this.callbackExecutor = callbackExecutor;
this.delegate = delegate;
}

RxJavaCallAdapterFactory返回的是Observable

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
@Override public Object adapt(Call<R> call) {
Observable<Response<R>> responseObservable = isAsync
? new CallEnqueueObservable<>(call)
: new CallExecuteObservable<>(call);
Observable<?> observable;
if (isResult) {
observable = new ResultObservable<>(responseObservable);
} else if (isBody) {
observable = new BodyObservable<>(responseObservable);
} else {
observable = responseObservable;
}
if (scheduler != null) {
observable = observable.subscribeOn(scheduler);
}
if (isFlowable) {
return observable.toFlowable(BackpressureStrategy.LATEST);
}
if (isSingle) {
return observable.singleOrError();
}
if (isMaybe) {
return observable.singleElement();
}
if (isCompletable) {
return observable.ignoreElements();
}
return observable;
}

经过上面几步操作 Call<List<Repo>> repos = service.listRepos("yeungeek"),返回了一个 OKHttpCall 对象。

发送网络请求

请求和 OKHttp 一样,分为同步请求和异步请求

同步请求

execute 首先会调用ExecutorCallbackCall的execute方法:

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

delegate代理实际是 OKHttpCall,最终会调用OKHttpCall的execute方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Override public Response<T> execute() throws IOException {
okhttp3.Call call;
......
call = rawCall;
if (call == null) {
try {
call = rawCall = createRawCall();
} catch (IOException | RuntimeException | Error e) {
throwIfFatal(e); // Do not assign a fatal error to creationFailure.
creationFailure = e;
throw e;
}
}
}
if (canceled) {
call.cancel();
}
return parseResponse(call.execute());
}

createRawCall

创建真正发送的请求Request对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
private okhttp3.Call createRawCall() throws IOException {
okhttp3.Call call = serviceMethod.toCall(args);
if (call == null) {
throw new NullPointerException("Call.Factory returned null.");
}
return call;
}
//调用serviceMethod的 toCall 方法
okhttp3.Call toCall(@Nullable Object... args) throws IOException {
//Request 的 builder 生成 Reuqest 对象
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 callFactory.newCall(requestBuilder.build());
}

parseResponse

调用OKHttp的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
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();
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();
}
}
if (code == 204 || code == 205) {
rawBody.close();
return Response.success(null, rawResponse);
}
ExceptionCatchingRequestBody catchingBody = new ExceptionCatchingRequestBody(rawBody);
try {
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选择数据转换器,对数据进行解析后,生成Response对象返回

异步请求

异步请求的流程和同步请求一样,就是再回调处理会进行线程切换
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) {
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);
}
});
}
});
}

代理执行加入了线程切换到逻辑,通过callbackExecutor切换到主线程
OKHttpCall的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
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
@Override public void enqueue(final Callback<T> callback) {
checkNotNull(callback, "callback == null");

okhttp3.Call call;
Throwable failure;

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

call = rawCall;
failure = creationFailure;
if (call == null && failure == null) {
try {
call = rawCall = createRawCall();
} catch (Throwable t) {
throwIfFatal(t);
failure = creationFailure = t;
}
}
}

if (failure != null) {
callback.onFailure(this, failure);
return;
}

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

call.enqueue(new okhttp3.Callback() {
@Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
Response<T> response;
try {
response = parseResponse(rawResponse);
} catch (Throwable e) {
callFailure(e);
return;
}

try {
callback.onResponse(OkHttpCall.this, response);
} catch (Throwable t) {
t.printStackTrace();
}
}

@Override public void onFailure(okhttp3.Call call, IOException e) {
callFailure(e);
}

private void callFailure(Throwable e) {
try {
callback.onFailure(OkHttpCall.this, e);
} catch (Throwable t) {
t.printStackTrace();
}
}
});
}

如果使用到RxJava,在上一节已经提到, adapt会进行适配,RxJava2CallAdapter的adapt方法中有对RxJava转换,具体逻辑实现这边先不展开

1
2
3
Observable<Response<R>> responseObservable = isAsync
? new CallEnqueueObservable<>(call)
: new CallExecuteObservable<>(call);

Retrofit中的HTTP实现

Retrofit真正请求网络,底层使用的是OKHttp,Refrofit主要负责网络请求接口的封装,看下源码中与HTTP相关的注解
Retrofit-HTTP
这些注解都是在接口上的声明,主要是HTTP的请求方法和参数,具体可以参考Android网络编程-HTTP/HTTPS,这里也不具体展开了

设计模式应用

我们再回顾下这张流程图:
retrofit-stay

构建者模式

这个模式运用的比较多,Retrofit的Builder,ServiceMethod的Builder等
设计模式可以参考建造者模式(Bulider模式)详解

工厂模式

在Retrofit 初始化,addCallAdapterFactory中的CallAdapter就是用工厂方法模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public interface CallAdapter<R, T> {
Type responseType();
T adapt(Call<R> call);

abstract class Factory {
public abstract @Nullable CallAdapter<?, ?> get(Type returnType, Annotation[] annotations,
Retrofit retrofit);

protected static Type getParameterUpperBound(int index, ParameterizedType type) {
return Utils.getParameterUpperBound(index, type);
}
protected static Class<?> getRawType(Type type) {
return Utils.getRawType(type);
}
}
}

实现Factory中抽象方法get,就会返回不同的 CallAdapter 对象
设计模式可以参考工厂方法模式(详解版)

外观模式(门面模式)

Retrofit 就是一个典型的外观类,它屏蔽了所有的实现细节,提供给使用者方便的接口,统一调用创建接口实例和网络请求配置的方法
设计模式可以参考外观模式(Facade模式)详解

策略模式

主要应用CallAdapter类的adapt方法,在 Retrofit addCallAdapterFactory,对应 Factory 生成不同的CallAdapter,adapt就可以调用到不同实现
CallAdapter就是一个Strategy,Retrofit 对应上下文(Context)
设计模式可以参考策略模式(策略设计模式)详解

适配器模式

还是在CallAdapter得到应用,Retrofit可以适配Android,Java8,RxJava,guava等平台, 不同平台有不同的特性,addCallAdapterFactory可以生成不同的平台的CallAdapter,把不同平台的特性,统一在一个接口中
设计模式可以参考适配器模式(Adapter模式)详解

代理模式

Retrofit实例的create方法,使用了动态代理模式,网络请求接口,都会调用到Proxy.newProxyInstance的 invoke 方法中

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.adapt(okHttpCall);
}
});
}

除了使用动态代理,Retrofit 还使用了静态代理模式,ExecutorCallbackCall的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);
        }
      });
    }
  });
}

设计模式可以参考代理模式(代理设计模式)详解
Retrofit使用了大量的设计模式,上面只是在主流过程使用到的,其他设计模式的应用,大家可以继续深入源码去分析,总之,Refrofit框架是非常值得深入研究的框架

参考

CATALOG
  1. 1. 基本使用
    1. 1.1. 创建网络请求接口
    2. 1.2. 创建Retrofit实例(使用建造者模式)
    3. 1.3. 创建网络接口实例
    4. 1.4. 发送网络请求
      1. 1.4.1. 同步
      2. 1.4.2. 异步
  2. 2. 请求流程
  3. 3. 源码分析
    1. 3.1. Retrofit初始化
      1. 3.1.1. Retrofit声明
      2. 3.1.2. Builder
      3. 3.1.3. baseUrl
      4. 3.1.4. ConverterFactory
      5. 3.1.5. CallAdapterFactory
      6. 3.1.6. build
    2. 3.2. 创建网络接口实例
      1. 3.2.1. create
      2. 3.2.2. loadServiceMethod
        1. 3.2.2.1. ServiceMethod
        2. 3.2.2.2. ServiceMethod.Builder
        3. 3.2.2.3. build
      3. 3.2.3. OKHttpCall
      4. 3.2.4. adapt
    3. 3.3. 发送网络请求
      1. 3.3.1. 同步请求
        1. 3.3.1.1. createRawCall
        2. 3.3.1.2. parseResponse
      2. 3.3.2. 异步请求
  4. 4. Retrofit中的HTTP实现
  5. 5. 设计模式应用
    1. 5.1. 构建者模式
    2. 5.2. 工厂模式
    3. 5.3. 外观模式(门面模式)
    4. 5.4. 策略模式
    5. 5.5. 适配器模式
    6. 5.6. 代理模式
  6. 6. 参考