本篇文章基于 retrofit2 的 2.5.0 版本。
首先我们想要分析源码,那就首先要会使用。看下简单用法:
public interface GitHubService {
@GET("users/{user}/repos")
Call<List<Repo>> listRepos(@Path("user") String user);
}
//创建Retrofit对象
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.build();
//创建service
GitHubService service = retrofit.create(GitHubService.class);
//创建Call
Call<List<Repo>> repos = service.listRepos("octocat");
//开始请求
repos.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) {
}
});
1.
从create方法入手,发现是动态代理。
调用Platform.get获取platform,暂时不知道是干嘛的,
接着看核心方法是loadServiceMethod(method).invoke(..);
2.
进入loadServiceMethod方法中,找到核心方法parseAnnotations()。从方法名上看出是解析注解的意思。
3.
进入parseAnnotations方法中,有两处核心代码。
RequestFactory.parseAnnotations(retrofit, method);
image.pngHttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
4.
先查看第一处核心代码RequestFactory.parseAnnotations(retrofit, method);
发现是使用了Builder模式创建了RequestFactory对象,看里面的方法,发现有一个create方法可以使用,进入方法里面。
- 先看第一段代码RequestBuilder,查看类里面的方法,字面意思是quest的构造器。
image.png - 再看第二段代码,用刚才的RequestBuilder对象创建了一个okhttp3.Request对象。查看里面的方法。知道大概是一个真正用来发起请求的类。先记着,还没有用到。
image.png
5.
现在回到第3个步骤继续。查看第二处核心代码HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
看注释可以了解到,ServiceMethod最好缓存起来使用,这样就能解释上面第2个步骤的缓存了。接着往下看核心代码:
①创建了CallAdapter。
追踪方法得知最终是由Retrofit对象的nextCallAdapter方法获取,内部是从callAdapterFactories这个List中取出,由于还没有查看Retrofit类的实现,暂时先放着。
②创建了ResponseConverter
追踪方法最终还是由Retrofit对象的nextResponseBodyConverter方法获取,与上一个类似,从converterFactories中取出,还是先放着。
③获取callFactory
这个更直接,从retrofit中取出成员变量callFactory。
④传入4个参数,创建一个HttpServiceMethod对象
最后看看HttpServiceMethod的构造方法,发现只是设置了变量。
6.
回到最初开始分析时的代码loadServiceMethod(method).invoke(..);
loadServiceMethod(method)实际上返回了HttpServiceMethod对象,查看里面的invoke方法。
其中4个变量都是构造方法传进来的,继续查看callAdapter.adapt方法。发现是一个接口方法。
T adapt(Call<R> call);
现在需要找到CallAdapter实现类。从上一步骤知道,这里的4个成员变量callAdapter,requestFactory,callFactory,responseConverter中除了requestFactory是刚才知道怎么创建的,其他都是从Retrofit对象中取出来的。
7.
现在需要知道Retrofit对象是怎么构建的,回到最初的简单用法中得知,Retrofit是从Retrofit.Builder的build方法创建的。
//创建Retrofit对象
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.build();
8.
现在从build方法入手。
/**
* 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() {
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.addAll(platform.defaultCallAdapterFactories(callbackExecutor));
// Make a defensive copy of the converters.
List<Converter.Factory> converterFactories = new ArrayList<>(
1 + this.converterFactories.size() + platform.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());
return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
}
①先看注释,明白这里就是通过一些配置来创建一个Retrofit对象,即Builder模式。
②看到callFactory的创建,默认是一个OkHttpClient对象,这一点注释也有说明。
③创建了一个Executor,使用了platform的defaultCallbackExecutor方法。
④创建了一个callAdapterFactories的List,把默认的CallAdapterFactories添加进去,还是使用了platform的方法,defaultCallAdapterFactories(callbackExecutor)。
⑤类似的实现方式,创建了converterFactories,也是添加了默认的对象。
⑥最后创建了一个Retrofit对象并返回,把参数设置到了对象中。
现在清楚了第6步骤使用的对象都是在Retrofit创建时就已经配置好了,但是我们继续查看时,发现它们都是接口,所以我们需要找出它们的实际对象,即是要找出它们实例化的代码。
9.
由于默认的Executor,CallAdapter,ConverterFactories都是由Platform的defaultXXXX方法创建的,所以分析一下platform这个对象其实是什么。回到第一步骤,Retrofit的create方法的return中的一行代码。
private final Platform platform = Platform.get();
进去看看
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();//这里看到Platform对象其实就是Android对象
}
} catch (ClassNotFoundException ignored) {
}
try {
Class.forName("java.util.Optional");
return new Java8();
} catch (ClassNotFoundException ignored) {
}
return new Platform();
}
现在知道了platform其实就是Android对象,我们查看Retrofit的build方法里的platform的调用:
- callbackExecutor = platform.defaultCallbackExecutor();
- platform.defaultCallAdapterFactories(callbackExecutor)
- platform.defaultConverterFactoriesSize()
- platform.defaultConverterFactories()
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();
}
//①默认的Executor是MainThreadExecutor
@Override public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
//②默认的CallAdapterFactories
@Override List<? extends CallAdapter.Factory> defaultCallAdapterFactories(
@Nullable Executor callbackExecutor) {
if (callbackExecutor == null) throw new AssertionError();
//CallAdapterFactory的默认对象,传入了callbackExecutor
ExecutorCallAdapterFactory executorFactory = new ExecutorCallAdapterFactory(callbackExecutor);
return Build.VERSION.SDK_INT >= 24
? asList(CompletableFutureCallAdapterFactory.INSTANCE, executorFactory)
: singletonList(executorFactory);
}
//默认的CallAdapterFactoriesSize
@Override int defaultCallAdapterFactoriesSize() {
return Build.VERSION.SDK_INT >= 24 ? 2 : 1;
}
//④默认的ConverterFactories
@Override List<? extends Converter.Factory> defaultConverterFactories() {
return Build.VERSION.SDK_INT >= 24
? singletonList(OptionalConverterFactory.INSTANCE)
: Collections.<Converter.Factory>emptyList();
}
//③默认的ConverterFactoriesSize
@Override int defaultConverterFactoriesSize() {
return Build.VERSION.SDK_INT >= 24 ? 1 : 0;
}
//默认的Executor中的execute方法就是用handler发消息,把操作放到主线程中
static class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
@Override public void execute(Runnable r) {
handler.post(r);
}
}
}
10.
现在回看第5个步骤,发现了使用的参数都是由这里的对象中取出的,那么可以继续分析第6步骤的方法:
image.png
callAdapter的获取,在nextCallAdapter方法中
核心callAdapterFactories.get(i).get(returnType, annotations, this);
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;
}
}
...
}
上面知道了callAdapterFactories的默认实现就是ExecutorCallAdapterFactory,进入该类查看get方法。
@Override public @Nullable CallAdapter<?, ?> get(
Type returnType, Annotation[] annotations, Retrofit retrofit) {
...
//创建了一个CallAdapter
return new CallAdapter<Object, Call<?>>() {
@Override public Type responseType() {
return responseType;
}
//核心方法
@Override public Call<Object> adapt(Call<Object> call) {
return new ExecutorCallbackCall<>(callbackExecutor, call);
}
};
}
到这里其实就是callAdapter的实现了。
11.
继续查看adapt方法,前文得知传入的call就是new OkHttpCall<>(requestFactory, args, callFactory, responseConverter));
查看内部类ExecutorCallbackCall:
我们使用时就是调用了Call的enqueue方法,这里看到enqueue方法的真正实现。
其中delegate是刚才传入的OkHttpCall对象,callbackExecutor我们知道其实是MainThreadExecutor对象,所以这里的enqueue方法中主要做了两件事:
- 调用OkHttpCall的enqueue发起请求
- 调用MainThreadExecutor的execute方法,内部其实就是用主线程的Handler切换到主线程去运行。
我们继续查看OkHttpCall的enqueue方法:
@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 {
//创建okhttp3.Call对象
call = rawCall = createRawCall();
} catch (Throwable t) {
throwIfFatal(t);
failure = creationFailure = t;
}
}
}
if (failure != null) {
callback.onFailure(this, failure);
return;
}
if (canceled) {
call.cancel();
}
//调用了okhttp3.Call对象的enqueue方法
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) {
throwIfFatal(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();
}
}
});
}
发现很长,其实里面的主要工作就是:
- 创建okhttp3.Call的对象
- 调用这个对象的enqueue方法
我们来看一下这个okhttp3.Call对象是什么,查看createRawCall()方法:
private okhttp3.Call createRawCall() throws IOException {
//这个callFactory其实就是okhttpClient
okhttp3.Call call = callFactory.newCall(requestFactory.create(args));
if (call == null) {
throw new NullPointerException("Call.Factory returned null.");
}
return call;
}
由上文得知这里的callFactory就是Retrofit.build()中创建的OkhttpClient对象。
这里的newCall方法就是创建一个OkHttp的Call了,所以说Retrofit是基于OkHttp来实现的。
@Override public Call newCall(Request request) {
return RealCall.newRealCall(this, request, false /* for web socket */);
}
总结
- 调用Retrofit.Builder的build方法,初始化必要的参数。
有baseUrl、callFactory、callbackExecutor、callAdapterFactories、converterFactories等。 - 调用retrofit的create方法,包装出一个自定义的接口GitHubService的Class。
内部实现是动态代理,具体实现是HttpServiceMethod的对象。其中包含了对接口方法注解的解析。 - 最后调用enqueue发起请求内部使用了okhttp。
谢谢大家能看到末尾,如果发现有错误的地方或者有疑问的地方请各位留言,谢谢!
网友评论