本文基于Retrofit2.5代码分析。 github.com/square/retr…
1. 分析思路:
从使用层面,一点点分析源码的具体实现。
2. 基本用法
2.1 Retrofit对象创建
// Create a very simple REST adapter which points the GitHub API.
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.addConverterFactory(GsonConverterFactory.create())
.build();
使用的是Builder模式,利用Builder来创建需要的配置。
2.2 定义API接口
public interface GitHub {
@GET("/repos/{owner}/{repo}/contributors")
Call<List<Contributor>> contributors(
@Path("owner") String owner,
@Path("repo") String repo);
}
首先,要定义一个接口,方法是具体的网络接口请求。 主要通过注解来设置网络请求的参数(POST/GET、Path),后面在调用接口时会通过注解获取。 2.3 创建接口对象
// Create an instance of our GitHub API interface.
GitHub github = retrofit.create(GitHub.class);
调用create()方法,创建接口对象。
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();
private final Object[] emptyArgs = new Object[0];
@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);
}
return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
}
});
}
通过动态代理方式Proxy.newProxyInstance来创建具体的对象。所有对代理对象的方法的调用,都会回调到invoke方法。
使用动态代理的好处,可以定义多个API接口,而Retrofit只需要利用动态代理,统一代码,不需要关心业务具体使用哪个接口。
2.4 调用API方法,获取回调
// Create a call instance for looking up Retrofit contributors.
Call<List<Contributor>> call = github.contributors("square", "retrofit");
对接口方法的调用,都会执行代理的InvocationHandler的invoke()方法。
Retrofit封装了一个ServiceMethod对象,下面看下如何创建的ServiceMethod。
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;
}
abstract class ServiceMethod<T> {
static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
// 先解析注解,获取Request相关参数,比如前面定义的POST/GET Path等
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.");
}
// 创建ServiceMethod对象
return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
}
abstract @Nullable T invoke(Object[] args);
}
下面重点介绍如何创建的ServiceMethod对象
/** Adapts an invocation of an interface method into an HTTP call. */
final class HttpServiceMethod<ResponseT, ReturnT> extends ServiceMethod<ReturnT> {
/**
* Inspects the annotations on an interface method to construct a reusable service method that
* speaks HTTP. This requires potentially-expensive reflection so it is best to build each service
* method only once and reuse it.
*/
static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
Retrofit retrofit, Method method, RequestFactory requestFactory) {
CallAdapter<ResponseT, ReturnT> callAdapter = createCallAdapter(retrofit, method);
......
Converter<ResponseBody, ResponseT> responseConverter =
createResponseConverter(retrofit, method, responseType);
okhttp3.Call.Factory callFactory = retrofit.callFactory;
return new HttpServiceMethod<>(requestFactory, callFactory, callAdapter, responseConverter);
}
......
}
主要有3个对象callFactory,callAdapter,responseConverter
callAdapter 把 retrofit2.Call 转为 T(注意和 okhttp3.Call 区分开来,retrofit2.Call 表示的是对一个 Retrofit 方法的调用),这个过程会发送一个 HTTP 请求,拿到服务器返回的数据(通过 okhttp3.Call 实现),并把数据转换为声明的 T 类型对象(通过 Converter<F, T> 实现);
responseConverter 是 Converter<ResponseBody, T> 类型,负责把服务器返回的数据(JSON、XML、二进制或者其他格式,由 ResponseBody 封装)转化为 T 类型的对象;
callFactory 负责创建 HTTP 请求,HTTP 请求被抽象为了 okhttp3.Call 类,它表示一个已经准备好,可以随时执行的 HTTP 请求;
分析下CallAdapter的创建过程
/**
* Returns the {@link CallAdapter} for {@code returnType} from the available {@linkplain
* #callAdapterFactories() factories}.
*
* @throws IllegalArgumentException if no call adapter available for {@code type}.
*/
public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) {
return nextCallAdapter(null, returnType, annotations);
}
/**
* Returns the {@link CallAdapter} for {@code returnType} from the available {@linkplain
* #callAdapterFactories() factories} except {@code skipPast}.
*
* @throws IllegalArgumentException if no call adapter available for {@code type}.
*/
public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType,
Annotation[] annotations) {
......
int start = callAdapterFactories.indexOf(skipPast) + 1;
for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
CallAdapter<?, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this);
if (adapter != null) {
return adapter;
}
}
......
}
是从Retrofit中的callAdapterFactories列表中获取的。
/**
* Create the {@link Retrofit} instance using the configured values.
* <p>
* Note: If neither {@link #client} nor {@link #callFactory} is called a default {@link
* OkHttpClient} will be created and used.
*/
public Retrofit build() {
......
// 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));
......
return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
}
可见,是根据用户设置和Platform共同生成的列表。
static class Android extends Platform {
@IgnoreJRERequirement // Guarded by API check.
@Override boolean isDefaultMethod(Method method) {
if (Build.VERSION.SDK_INT < 24) {
return false;
}
return method.isDefault();
}
@Override public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
@Override List<? extends CallAdapter.Factory> defaultCallAdapterFactories(
@Nullable Executor callbackExecutor) {
if (callbackExecutor == null) throw new AssertionError();
ExecutorCallAdapterFactory executorFactory = new ExecutorCallAdapterFactory(callbackExecutor);
return Build.VERSION.SDK_INT >= 24
? asList(CompletableFutureCallAdapterFactory.INSTANCE, executorFactory)
: singletonList(executorFactory);
}
}
由前面代码可知,Retrofit利用Factory模式,通过调用CallAdater.Factory.get()方法创建的CallAdapter对象。
Converter创建源码,同CallAdapter,也是利用Facotry模式,通过调用Converter.Factory.get()方法创建的Convert对象。
CallFactory是OkHttp中的Call.Factory的对象,默认在Retrofit.Builder中创建,如果使用者,不设置,则创建。默认使用OkHttpClient。
public Retrofit build() {
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new OkHttpClient();
}
......
}
以上,创建完成ServiceMethod。
下面开始分析ServiceMethod.invoke()方法
@Override ReturnT invoke(Object[] args) {
return callAdapter.adapt(
new OkHttpCall<>(requestFactory, args, callFactory, responseConverter));
}
就是执行CallAdapter.adapt()方法。
我们知道CallAdapter是通过CallAdater.Factory.get()创建的。
Android中使用的是ExecutorCallAdapterFactory来完成创建的。
final class ExecutorCallAdapterFactory extends CallAdapter.Factory {
final Executor callbackExecutor;
ExecutorCallAdapterFactory(Executor callbackExecutor) {
this.callbackExecutor = callbackExecutor;
}
@Override public @Nullable 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);
}
};
}
// 只是做了一层封装,具体的执行,都是调用的构造方法中的Call<T>对象。即都是调用的OkHttpCall
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()) {
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();
}
......
}
}
以上即完成了接口方法的调用,会返回retrofit2.Call对象。
2.4 通过回调Call调用执行具体的网络请求
// Fetch and print a list of the contributors to the library.
List<Contributor> contributors = call.execute().body();
或
call.enqueue(new Callback<List<Contributor>>() {
@Override
public void onResponse(Call<List<Contributor>> call, Response<List<Contributor>> response) {
}
@Override
public void onFailure(Call<List<Contributor>> call, Throwable t) {
}
});
OkHttpCall其实是对okhttp3.Call的封装,最后都是调用okhttp3.Call的enqueue和execute方法。
到此,Retrofit的流程基本分析完成了。
最后提供一张整体框架图
参考: