1 使用回顾
我们在前面博文《Android网络编程(十一) 之 Retrofit2框架的使用》中已经对Retrofit的使用进行过介绍。今天我们接着往下来阅读Retrofit的关键源码从而它进行更加深入的理解。开始前,先来回顾一下简单的使用,通过使用步骤来深入分析每行代码背后的原理,代码如:
// 0 创建一个网络请求的接口
public interface AppInfoService {
@GET("url.json")
Call<List<AppInfo>> getAppInfoList(@Query("id") int id);
}
private void getRequest() {
// 1 创建 Retrofit 对象,输入请求URL、转换器等
Retrofit retorfit = new Retrofit.Builder()
.baseUrl("https://api.xx.com/ ")
.addConverterFactory(GsonConverterFactory.create())
.build();
// 2 通过Retrofit的create创建自定义的请求接口对象
AppInfoService appInfoService = retorfit.create(AppInfoService.class);
// 3 通过调用请求接口方法创建Call对象
Call<List<AppInfo>> call = appInfoService.getAppInfoList(123);
// 4 发起同步或异步的网络请求
// try {
// Response<List<AppInfo>> response = call.execute();
// List<AppInfo> appInfos = response.body();
// Log.e("zyx", appInfos.toString());
//
// } catch (IOException e) {
// e.printStackTrace();
// }
call.enqueue(new Callback<List<AppInfo>>() {
@Override
public void onResponse(Call<List<AppInfo>> call, Response<List<AppInfo>> response) {
List<AppInfo> appInfos = response.body();
Log.e("zyx", appInfos.toString());
}
@Override
public void onFailure(Call<List<AppInfo>> call, Throwable t) {
Log.e("zyx", t.toString());
}
});
}
可见其步骤大概是:
0 创建一个自定义的网络请求的接口,里头包含请求方式、请求服务端接口名和请求参数的传入的方法;
1 创建 Retrofit 对象,输入请求URL、转换器等;
2 通过Retrofit的create创建自定义的请求接口对象;
3 通过调用请求接口方法创建Call对象;
4 发起同步或异步的网络请求。
2 原理分析
2.1 创建Retrofit对象
Retrofit对象的创建过程也是使用了构造器模式进行的初始化。首先,Builder方法最终会调用到Platform类的findPlatform方法。
Retrofit.java
public static final class Builder {
// ……
Builder(Platform platform) {
this.platform = platform;
}
public Builder() {
this(Platform.get());
}
}
Platform.java
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();
}
}
上述代码可见,findPlatform方法内部会根据不同的运行平台来创建不同的Platform对象。接着调用其build方法。
Retrofit.java
public final class Retrofit {
public static final class Builder {
private final Platform platform;
private @Nullable okhttp3.Call.Factory callFactory;
private @Nullable 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;
// ……
public Retrofit build() {
// 关键代码1,判断baseUrl是否为空
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
// 关键代码2,获得或创建 网络请求执行器工厂 okhttp3.Call.Factory对象
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new OkHttpClient();
}
// 关键代码3,获得或创建回调方法执行器Executor对象
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
// 关键代码4,创建 网络请求适配器工厂CallAdapter.Factory列表,
// 并将callAdapterFactories和上面的callbackExecutor对象创建出默认的defaultCallAdapterFactories添加其中
// Make a defensive copy of the adapters and add the default Call adapter.
List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));
// 关键代码5,创建 数据转换器工厂Converter.Factory列表
// Make a defensive copy of the converters.
List<Converter.Factory> converterFactories = new ArrayList<>(1 + this.converterFactories.size() + latform.defaultConverterFactoriesSize());
// 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);
converterFactories.addAll(platform.defaultConverterFactories());
// 关键代码6,实例化Retrofit对象
return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
}
}
}
Build方法里逻辑很清晰,主要就是5件事情:
- 判断baseurl是否为空,baseurl的值就是通过. baseUrl方法进行设置。
- 获得网络请求执行器工厂callFactory对象值,若为空,则创建一个OkHttpClient对象,所以很明显Retrofit默认使用OkHttp进行网络请求,callFactory的值可通过. client方法进行设置。
- 获得回调方法执行器callbackExecutor对象值,若为空,则创建一个默认的,该默认的是一个MainThreadExecutor对象且它内部有一个带有Looper的Handler,我们后面再来讨论它。callbackExecutor的值可通过. callbackExecutor方法进行设置。
- 获得网络请求适配器工厂callAdapterFactories的值,将其添加到列表中,callAdapterFactories的值可通过. addCallAdapterFactory方法进行设置。列表创建完后再将关键代码3中的callbackExecutor对象添加其中。
- 创建一个数据转换器工厂Converter.Factory列表,之后添加内置的数据转换器BuiltInConverters和默认的数据转换器工厂defaultConverterFactories,其中还获得converterFactories的值,也将其添加到列表中,converterFactories的值可通过. addConverterFactory方法进行添加。
- 最后将上述对象传入Retrofit的构造函数中去实例化Retrofit对象,注意validateEagerly值表示提前验证,可通过. validateEagerly方法进行设置。
2.2通过Retrofit的create创建自定义的请求接口对象
如示例中代码 AppInfoService appInfoService = retorfit.create(AppInfoService.class);,Retrofit的create方法是一个泛型的方法,参数就是自定义的接口类型,返回值是一个Proxy.newProxyInstance动态代理对象,请看代码。
Retrofit.java
public final class Retrofit {
// ……
@SuppressWarnings("unchecked") // Single-interface proxy creation guarded by parameter safety.
public <T> T create(final Class<T> service) {
Utils.validateServiceInterface(service);
// 关键代码1,是否提前验证
if (validateEagerly) {
eagerlyValidateMethods(service);
}
// 关键代码2,创建一个用于网络请求接口的动态代理对象并返回
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
new InvocationHandler() {
private final Platform platform = Platform.get();
private final Object[] emptyArgs = new Object[0];
@Override public @Nullable 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);
}
// 关键代码3,加载网络请求接口里的方法,并执行
return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
}
});
}
private void eagerlyValidateMethods(Class<?> service) {
Platform platform = Platform.get();
for (Method method : service.getDeclaredMethods()) {
if (!platform.isDefaultMethod(method) && !Modifier.isStatic(method.getModifiers())) {
loadServiceMethod(method);
}
}
}
// ……
}
- create方法内首先会判断validateEagerly变量是否为true,即是否提前验证,eagerlyValidateMethods方法其实也就是提前去触发关键代码3中loadServiceMethod方法逻辑。
- 关键代码2处,此处是创建了一个用于网络请求接口的动态代理对象,也就是当我们去调用使用回调示例中的AppInfoService的getAppInfoList方法时,最终会调用InvocationHandler的invoke方法。
- 关键代码3处,是加载网络请求的接口里的方法并执行,method就是我们自定义的getAppInfoList方法。
2.3通过调用请求接口方法创建Call对象
如示例中代码Call<List<AppInfo>> call = appInfoService.getAppInfoList(123);,该方法返回一个Call对象,从2.2中得知该方法最终会调用到Retrofit的loadServiceMethod方法返回对象的invoke方法中去,所以我们继续来看loadServiceMethod方法和invoke方法的代码。
2.3.1 loadServiceMethod方法
Retrofit.java
public final class Retrofit {
private final Map<Method, ServiceMethod<?>> serviceMethodCache = new ConcurrentHashMap<>();
// ……
ServiceMethod<?> loadServiceMethod(Method method) {
ServiceMethod<?> result = serviceMethodCache.get(method);
if (result != null) return result;
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
// 关键代码
result = ServiceMethod.parseAnnotations(this, method);
serviceMethodCache.put(method, result);
}
}
return result;
}
// ……
}
loadServiceMethod方法内先从静态Map对象serviceMethodCache中读取是否存在之前创建过的网络请求实例,如果有就直接返回。否则通过ServiceMethod.parseAnnotations方法创建再添加到serviceMethodCache中去最后返回新创建对象。
ServiceMethod.java
abstract class ServiceMethod<T> {
static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
// 关键代码1,创建一个请求工厂RequestFactory对象
RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);
Type returnType = method.getGenericReturnType();
if (Utils.hasUnresolvableType(returnType)) {
throw methodError(method,
"Method return type must not include a type variable or wildcard: %s", returnType);
}
if (returnType == void.class) {
throw methodError(method, "Service methods cannot return void.");
}
// 关键代码2,创建HttpServiceMethod对象并返回
return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
}
abstract @Nullable T invoke(Object[] args);
}
方法就是做了两件事情:
- 通过RequestFactory类的parseAnnotations方法创建一个请求工厂。
- 最终创建一个HttpServiceMethod对象并返回。
下面我们继续来分析RequestFactory的parseAnnotations方法和HttpServiceMethod的parseAnnotations方法逻辑。
2.3.1.1RequestFactory的parseAnnotations方法
RequestFactory.java
final class RequestFactory {
static RequestFactory parseAnnotations(Retrofit retrofit, Method method) {
return new Builder(retrofit, method).build();
}
private final Method method;
private final HttpUrl baseUrl;
final String httpMethod;
private final @Nullable String relativeUrl;
private final @Nullable Headers headers;
private final @Nullable MediaType contentType;
private final boolean hasBody;
private final boolean isFormEncoded;
private final boolean isMultipart;
private final ParameterHandler<?>[] parameterHandlers;
final boolean isKotlinSuspendFunction;
RequestFactory(Builder builder) {
method = builder.method;
baseUrl = builder.retrofit.baseUrl;
httpMethod = builder.httpMethod;
relativeUrl = builder.relativeUrl;
headers = builder.headers;
contentType = builder.contentType;
hasBody = builder.hasBody;
isFormEncoded = builder.isFormEncoded;
isMultipart = builder.isMultipart;
parameterHandlers = builder.parameterHandlers;
isKotlinSuspendFunction = builder.isKotlinSuspendFunction;
}
// ……
static final class Builder {
// ……
Builder(Retrofit retrofit, Method method) {
this.retrofit = retrofit;
this.method = method;
this.methodAnnotations = method.getAnnotations();
this.parameterTypes = method.getGenericParameterTypes();
this.parameterAnnotationsArray = method.getParameterAnnotations();
}
RequestFactory build() {
// ……
return new RequestFactory(this);
}
private void parseMethodAnnotation(Annotation annotation) {
if (annotation instanceof DELETE) {
parseHttpMethodAndPath("DELETE", ((DELETE) annotation).value(), false);
} else if (annotation instanceof GET) {
parseHttpMethodAndPath("GET", ((GET) annotation).value(), false);
} else if (annotation instanceof HEAD) {
parseHttpMethodAndPath("HEAD", ((HEAD) annotation).value(), false);
} else if (annotation instanceof PATCH) {
parseHttpMethodAndPath("PATCH", ((PATCH) annotation).value(), true);
} else if (annotation instanceof POST) {
parseHttpMethodAndPath("POST", ((POST) annotation).value(), true);
} else if (annotation instanceof PUT) {
parseHttpMethodAndPath("PUT", ((PUT) annotation).value(), true);
} else if (annotation instanceof OPTIONS) {
parseHttpMethodAndPath("OPTIONS", ((OPTIONS) annotation).value(), false);
} else if (annotation instanceof HTTP) {
HTTP http = (HTTP) annotation;
parseHttpMethodAndPath(http.method(), http.path(), http.hasBody());
} else if (annotation instanceof retrofit2.http.Headers) {
String[] headersToParse = ((retrofit2.http.Headers) annotation).value();
if (headersToParse.length == 0) {
throw methodError(method, "@Headers annotation is empty.");
}
headers = parseHeaders(headersToParse);
} else if (annotation instanceof Multipart) {
if (isFormEncoded) {
throw methodError(method, "Only one encoding annotation is allowed.");
}
isMultipart = true;
} else if (annotation instanceof FormUrlEncoded) {
if (isMultipart) {
throw methodError(method, "Only one encoding annotation is allowed.");
}
isFormEncoded = true;
}
}
// ……
}
可见RequestFactory的parseAnnotations方法其实就是传入Retrofit对象和method参数,然后通过读取method中定义的注解值(类中的parseMethodAnnotation方法),得到各种网络请求参数的一个对象。
2.3.1.2 HttpServiceMethod的parseAnnotations方法
获得RequestFactory对象后,就是作为参数传到HttpServiceMethod的parseAnnotations方法去,再看代码。
HttpServiceMethod.java
abstract class HttpServiceMethod<ResponseT, ReturnT> extends ServiceMethod<ReturnT> {
static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
Retrofit retrofit, Method method, RequestFactory requestFactory) {
// ……
// 关键代码1,从Retrofit对象中的 网络请求适配器工厂 获得 网络请求适配器callAdapter和其请求类型
CallAdapter<ResponseT, ReturnT> callAdapter = createCallAdapter(retrofit, method, adapterType, annotations);
Type responseType = callAdapter.responseType();
if (responseType == okhttp3.Response.class) {
throw methodError(method, "'" + getRawType(responseType).getName()
+ "' is not a valid response body type. Did you mean ResponseBody?");
}
if (responseType == Response.class) {
throw methodError(method, "Response must include generic type (e.g., Response<String>)");
}
// TODO support Unit for Kotlin?
if (requestFactory.httpMethod.equals("HEAD") && !Void.class.equals(responseType)) {
throw methodError(method, "HEAD method must use Void as response type.");
}
// 关键代码2,从Retrofit对象中的 数据转换器工厂 获得 数据转换器 responseConverter
Converter<ResponseBody, ResponseT> responseConverter = createResponseConverter(retrofit, method, responseType);
// 关键代码3,从Retrofit对象中的 获得 网络请求执行器工厂 callFactory
okhttp3.Call.Factory callFactory = retrofit.callFactory;
// 关键代码4,根据类型创建不同的HttpServiceMethod实现
if (!isKotlinSuspendFunction) {
return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
} else if (continuationWantsResponse) {
//noinspection unchecked Kotlin compiler guarantees ReturnT to be Object.
return (HttpServiceMethod<ResponseT, ReturnT>) new SuspendForResponse<>(requestFactory,
callFactory, responseConverter, (CallAdapter<ResponseT, Call<ResponseT>>) callAdapter);
} else {
//noinspection unchecked Kotlin compiler guarantees ReturnT to be Object.
return (HttpServiceMethod<ResponseT, ReturnT>) new SuspendForBody<>(requestFactory,
callFactory, responseConverter, (CallAdapter<ResponseT, Call<ResponseT>>) callAdapter,
continuationBodyNullable);
}
}
// ……
}
HttpServiceMethod的parseAnnotations方法里会去获取之前在Retrofit对象中的 网络请求适配器callAdapter、数据转换器responseConverter、网络请求执行器工厂callFactory 以及 通过参数传入的请求工厂RequestFactory作为参数,去根据不同类型创建三种分别是CallAdapted,SuspendForResponse和SuspendForBody的HttpServiceMethod对象。其中SuspendForResponse和SuspendForBody是Kotlin suspend 方法的支持,所以我们只看CallAdapted便可以了。
HttpServiceMethod.java
static final class CallAdapted<ResponseT, ReturnT> extends HttpServiceMethod<ResponseT, ReturnT> {
private final CallAdapter<ResponseT, ReturnT> callAdapter;
CallAdapted(RequestFactory requestFactory, okhttp3.Call.Factory callFactory,
Converter<ResponseBody, ResponseT> responseConverter,
CallAdapter<ResponseT, ReturnT> callAdapter) {
super(requestFactory, callFactory, responseConverter);
this.callAdapter = callAdapter;
}
@Override protected ReturnT adapt(Call<ResponseT> call, Object[] args) {
return callAdapter.adapt(call);
}
}
2.3.2 invoke方法
看回上面的 return loadServiceMethod(method).invoke(args != null ? args : emptyArgs); 代码,当loadServiceMethod方法返回了ServiceMethod对象后,接着就是调用它的invoke方法。
ServiceMethod.java
abstract class ServiceMethod<T> {
// ……
abstract @Nullable T invoke(Object[] args);
}
invoke方法的实现在HttpServiceMethod类中。
HttpServiceMethod.java
abstract class HttpServiceMethod<ResponseT, ReturnT> extends ServiceMethod<ReturnT> {
// ……
@Override final @Nullable ReturnT invoke(Object[] args) {
Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
return adapt(call, args);
}
protected abstract @Nullable ReturnT adapt(Call<ResponseT> call, Object[] args);
}
Invoke方法很简单,就是调用adapt方法,也就是HttpServiceMethod的实现类CallAdapted中的adapt方法。其代码已经在上面贴过。这里请记住第一个参数call是OkHttpCall。
HttpServiceMethod.java
static final class CallAdapted<ResponseT, ReturnT> extends HttpServiceMethod<ResponseT, ReturnT> {
//……
@Override protected ReturnT adapt(Call<ResponseT> call, Object[] args) {
return callAdapter.adapt(call);
}
}
最终就是 网络请求适配器callAdapter的adapt方法。
这个网络请求适配器callAdapter就是在HttpServiceMethod的parseAnnotations方法中关键代码1中,从Retrofit对象中的 网络请求适配器工厂 获得的 网络请求适配器callAdapter。回顾一下上面创建Retrofit对象中的 网络请求适配器工厂,当时提到该 网络请求适配器工厂callAdapterFactories的值可通过. addCallAdapterFactory方法进行设置 和 默认的defaultCallAdapterFactories
Platform.java
List<? extends CallAdapter.Factory> defaultCallAdapterFactories(@Nullable Executor callbackExecutor) {
return singletonList(new DefaultCallAdapterFactory(callbackExecutor));
}
DefaultCallAdapterFactory.java
final class DefaultCallAdapterFactory extends CallAdapter.Factory {
private final @Nullable Executor callbackExecutor;
DefaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
this.callbackExecutor = callbackExecutor;
}
@Override public @Nullable CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
if (getRawType(returnType) != Call.class) {
return null;
}
if (!(returnType instanceof ParameterizedType)) {
throw new IllegalArgumentException("Call return type must be parameterized as Call<Foo> or Call<? extends Foo>");
}
final Type responseType = Utils.getParameterUpperBound(0, (ParameterizedType) returnType);
final Executor executor = Utils.isAnnotationPresent(annotations, SkipCallbackExecutor.class) ? null : callbackExecutor;
return new CallAdapter<Object, Call<?>>() {
@Override public Type responseType() {
return responseType;
}
@Override public Call<Object> adapt(Call<Object> call) {
return executor == null ? call : new ExecutorCallbackCall<>(executor, call);
}
};
}
}
最终,如果我们没有通过. addCallAdapterFactory方法指定callAdapter的话,invoke方法会执行到DefaultCallAdapterFactory类中,所以创建Call对象就是ExecutorCallbackCall对象。
DefaultCallAdapterFactory的ExecutorCallbackCall构造方法接收两个参数。先说说第二个参数call,我们在HttpServiceMethod的invoke中可知是一个OkHttpCall对象。而第一个参数executor是在创建Retrofit对象时的回调方法执行器callbackExecutor,如果当时不通过.callbackExecutor方法设置的话,它默认是platform.defaultCallbackExecutor();,一个MainThreadExecutor对象,它的源码如下,可见它内部有一个带有Looper的Handler。
Platform.java
class Platform {
// ……
static class Android extends Platform {
// ……
@Override public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
// ……
static class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
@Override public void execute(Runnable r) {
handler.post(r);
}
}
}
}
2.4发起网络请求
获得Call对象后就是最后发请网络请求。从上面我们得知Call对象就是DefaultCallAdapterFactory.ExecutorCallbackCall,所以无论是异步还是同步的请求,都是调用了DefaultCallAdapterFactory.ExecutorCallbackCall里的enqueue和execute方法。源码如下。
DefaultCallAdapterFactory.java
final class DefaultCallAdapterFactory extends CallAdapter.Factory {
// ……
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 Response<T> execute() throws IOException {
return delegate.execute();
}
// ……
}
enqueue和execute方法内都是代理了delegate对象执行,而delegate对象就是OkHttpCall对象。所以我们只看OkHttpCall的enqueue逻辑就会明白了。
OkHttpCall.java
final class OkHttpCall<T> implements Call<T> {
// ……
@Override public void enqueue(final Callback<T> callback) {
// ……
okhttp3.Call call;
// ……
if (call == null && failure == null) {
try {
// 关键代码1,创建okhttp3的call对象
call = rawCall = createRawCall();
} catch (Throwable t) {
// ……
}
}
}
// ……
// 关键代码2,执行call对象的异常请求
call.enqueue(new okhttp3.Callback() {
@Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
Response<T> response;
try {
// 关键代码3,获得请求结果进行解析
response = parseResponse(rawResponse);
} catch (Throwable e) {
throwIfFatal(e);
callFailure(e);
return;
}
try {
callback.onResponse(OkHttpCall.this, response);
} catch (Throwable t) {
throwIfFatal(t);
t.printStackTrace(); // TODO this is not great
}
}
@Override public void onFailure(okhttp3.Call call, IOException e) {
callFailure(e);
}
// ……
});
}
private okhttp3.Call createRawCall() throws IOException {
okhttp3.Call call = callFactory.newCall(requestFactory.create(args));
if (call == null) {
throw new NullPointerException("Call.Factory returned null.");
}
return call;
}
}
关键代码1中通过createRawCall方法创建了一个okhttp3的call对象,接着在关键代码2中去执行okhttp3的异常请求,然后在关键代码3中通过parseResponse方法进行了请求结果的解析和封装。最后结果再回调到ExecutorCallbackCall中去,而我们知道okhttp3的回调是执行在子线程中的,在ExecutorCallbackCall也就是MainThreadExecutor对象,因为它本身带有Looper的Handler,所以最终将结果回调到主线程中去执行。
同理,同步的方法execute也是调用了okhttp3的call对象的execute方法,最终也是通过parseResponse方法进行了请求结果的解析和封装。
3 总结
至此,关于Retrofit2框架就介绍完毕,虽然过程中省略了大量的细节,但整体过程原理还是通过源码了解很多。那我们现在用简短的话来总结一下原理:
第1、创建Retrofit对象,内部先会根据不同的运行平台来创建不同的Platform对象。然后通过构造器模式进行参数的初始化,如使用:
- 使用baseUrl方法设置要访问的URL;
- 选择性使用callFactory方法创建“网络请求执行器工厂”callFactory,若不使用该方法,则会创建一个OkHttpClient对象;
- 选择性使用callbackExecutor方法创建“回调方法执行器”callbackExecutor,若不使用该方法,则创建一个默认的defaultCallbackExecutor,它是一个带Looper的Handler的MainThreadExecutor对象;
- 选择性使用addCallAdapterFactory方法添加“网络请求适配器工厂”,以及追加一个默认的网络请求器DefaultCallAdapterFactory;
- 选择性使用addConverterFactory方法添加“数据转换器工厂”中;
- 最后通过上述创建的对象进行实例化Retrofit。
第2、通过Retrofit的泛型方法create并会传入自定义的接口类型来创建自定义的请求接口对象,该对象是使用了Proxy.newProxyInstance的动态代理对象。
第3、通过调用自定义的请求接口方法创建Call对象,
- 内部先获取定义方法中的注解值创建一个“请求工厂”RequestFactory,然后再获取前面Retrofit对象中的“网络请求适配器”callAdapter、“数据转换器”responseConverter、“网络请求执行器工厂”callFactory 以及 刚创建的“请求工厂”RequestFactory,根据类型创建出继承于HttpServiceMethod的CallAdapted对象;
- 因为使用了动态代理,所以最后会调用到CallAdapted对象的adapt方法去,又因为默认的“网络请求适配器”就是DefaultCallAdapterFactory对象,所以最后adapt方法内部创建的Call对象就是ExecutorCallbackCall对象。
第4、发起网络请求,就是通过DefaultCallAdapterFactory.ExecutorCallbackCall的enqueue和execute方法来执行异步和同步。这两个方法都是通过一个OkHttpCall对象来完成,OkHttpCall内部就是封装了okhttp3的网络请求。待请求完成后更是将结果回调回到ExecutorCallbackCall里,再通过带Looper的Handler的MainThreadExecutor回调方法执行器将结果回调到调用方的主线程中去。