版权声明:本文为博主原创文章,未经博主允许不得转载
Github:github.com/Darkwh
若有错误或疑问欢迎小伙伴们留言评论
友情提示!!!
本人英文渣,文章中哪些单词翻译的不够形象的话。。。。那你到是来打我呀O(∩_∩)O 另外本篇文章强烈建议打开源码参考阅读,否则造成强烈不适概不负责~
系列回顾
前言
上一篇为大家介绍了retrofit的使用和其中几个比较重要的类,本篇将会顺着retrofit的使用来详细分析源码。本文为了节省篇幅,代码中都添加了中文注释,这里我就讲一下我认为值得讲解的地方,小伙伴们记得看注释啊。那么接下来让我们正式开始吧!!
第一步:创建Retrofit对象
val retrofit: Retrofit = Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl("http://gank.io/api/")
.build()
首先Retrofit采用建造者模式,这种模式大家应该都不陌生了,这里就不多介绍了。
addConverterFactory和baseUrl方法均是为builder的参数成员赋值,赋值之前会有一些非空或URL格式的检查,代码很简单。让我们直接聚焦到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;
//如果未指定callFactory,则默认创建一个OkHttpClint来使用
if (callFactory == null) {
callFactory = new OkHttpClient();
}
Executor callbackExecutor = this.callbackExecutor;
//如果未指定callbackExecutor,则获取默认的callbackExecutor
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
//做一次深度拷贝
List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);
//此处将默认的CallAdapter放到集合末尾
adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
//做一次深度拷贝
List<Converter.Factory> converterFactories =
new ArrayList<>(1 + this.converterFactories.size());
//此处将默认的Converter.Factory实现添加到集合首位置
converterFactories.add(new BuiltInConverters());
converterFactories.addAll(this.converterFactories);
//返回Retrofit实例
return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,
callbackExecutor, validateEagerly);
}
在build的时候,callFactory、callbackExecutor未做显示指定的时候,都会采用默认的实现。而至于adapterFactories和converterFactories这两个集合变量,则分别将内置的实例添加到末尾和首位置。
获取默认实现的时候涉及到了Platform和BuiltInConverters这两个类,我们来看一下这两个类,首先来看Platform:
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方法,Android平台自然会返回Android这样一个Platform的子类
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();
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);
}
}
}
可以看到默认的CallbackExecutor为MainThreadExecutor,利用handler在回到主线程处理。默认的CallAdapterFactory为 ExecutorCallAdapterFactory
final class ExecutorCallAdapterFactory extends CallAdapter.Factory {
final Executor callbackExecutor;
ExecutorCallAdapterFactory(Executor callbackExecutor) {
this.callbackExecutor = callbackExecutor;
}
@Override
public 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);
}
};
}
}
ExecutorCallAdapterFactory提供一个匿名的CallAdapter实现,该匿名对象的adapt方法会返回ExecutorCallbackCall对象
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 Request request() {
return delegate.request();
}
}
静态代理模式,调用目标对象,即第一篇为大家介绍过的Call接口的内置实现OkHttpCall对象,并将通过接口将成功失败结果回调回来。
BuiltInConverters这个类我们放到后面去讲解。
第二步:创建自定义接口的代理对象
val service: TestService = retrofit.create(TestService::class.java)
create方法是整个Retrofit最精髓的一段代码,它的作用是通过Java的动态代理方式来返回一个你定义好的接口的动态代理对象,不明白动态代理的小伙伴们可以自行百度一下,网上有很多的讲解。看一下这段代码:
public <T> T create(final Class<T> service) {
//检查接口,如果目标类不是一个接口或继承于其他的接口则抛出异常
Utils.validateServiceInterface(service);
//是否提前将method对象转换为ServiceMethod并缓存
if (validateEagerly) {
eagerlyValidateMethods(service);
}
//通过Java的动态代理返回代理对象
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.
// 如果该方法属于Object的方法,则直接调用
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
// Android平台该if分支不会执行
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
//将该方法映射为ServiceMethood
ServiceMethod<Object, Object> serviceMethod =
(ServiceMethod<Object, Object>) loadServiceMethod(method);
//创建OkHttpCall对象
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
//利用CallAdapter将okHttpCall转换为指定的类型(默认为Call<Object>)
return serviceMethod.callAdapter.adapt(okHttpCall);
}
});
}
让我们将这段代码分开讲解
1.检查自定义的接口
Utils.validateServiceInterface(service);
对传入的自定义接口进行检查,如果该类并非一个接口或继承于另一个接口,则抛出异常。
2.是否提前将自定义接口中的方法都映射为ServiceMethod并缓存
//是否提前将method对象转换为ServiceMethod并缓存
if (validateEagerly) {
eagerlyValidateMethods(service);
}
可以通过Retrofit.Builder的validateEagerly方法来设置是否提前映射接口方法并缓存
3.创建并返回动态代理对象
//通过Java的动态代理返回代理对象
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.
// 如果该方法属于Object的方法,则直接调用
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
// Android平台该if分支不会执行
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
//将该方法映射为ServiceMethood
ServiceMethod<Object, Object> serviceMethod =
(ServiceMethod<Object, Object>) loadServiceMethod(method);
//创建OkHttpCall对象
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
//利用CallAdapter将okHttpCall转换为指定的类型(默认为Call<Object>)
return serviceMethod.callAdapter.adapt(okHttpCall);
}
});
首先如果调用的方法属于Object类的方法,例如notify,getClass等,则会直接调用。而第二个if在Android平台不会执行,参考Platform中代码,其invokeDefaultMethod方法总会返回false,最后代码会执行到最下面三行。让我们另起一个篇幅来看看这几行代码到底做了神马!!(第三步中讲解)
第三步:通过动态代理对象调用接口方法返回Call对象
val call: Call<MsgBean> = service.getMsg()
在我们调用自定义接口的方法后,代码会进入到retrofit.create方法中的那个匿名InvocationHandler对象中的invoke方法中,一般情况下都会跳过前面两个if分支执行最下面的三行代码,并返回一个Call对象(上面说过了内置的Call对象为ExecutorCallbackCall)。来让我们一行行开始看看这几行代码到底做了什么:
//将该方法映射为ServiceMethood
ServiceMethod<Object, Object> serviceMethod = (ServiceMethod<Object, Object>) loadServiceMethod(method);
调用loadServiceMethod方法并返回ServiceMethod对象,看下loadServiceMethod:
ServiceMethod<?, ?> loadServiceMethod(Method method) {
//首先从加载过的缓存列表中去取
ServiceMethod<?, ?> result = serviceMethodCache.get(method);
//如果缓存过则直接返回
if (result != null) return result;
//双重锁,考虑到同步问题
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
//通过ServiceMethod.Builder来创建ServiceMethod对象
result = new ServiceMethod.Builder<>(this, method).build();
//缓存到集合中
serviceMethodCache.put(method, result);
}
}
return result;
}
loadServiceMethod方法会做这么几件事,首先从缓存列表中去获取缓存实例,如果未做缓存(即为null)则通过ServiceMethod.Builder来创建ServiceMethod,然后缓存并返回。serviceMethodCache的定义是这样子:
private final Map<Method, ServiceMethod<?, ?>> serviceMethodCache = new ConcurrentHashMap<>();
ConcurrentHashMap是一个线程安全且拥有很好的并发写入能力的HashMap。
顺着代码我们继续分析ServiceMethod.Builder这个类,一下进入ServiceMethod分析
ServiceMethod
ServiceMethod.Builder
Builder(Retrofit retrofit, Method method) {
this.retrofit = retrofit;
this.method = method;
this.methodAnnotations = method.getAnnotations();
this.parameterTypes = method.getGenericParameterTypes();
this.parameterAnnotationsArray = method.getParameterAnnotations();
}
ServiceMethod.Builder接收从外部传入的Retrofit(即第一步中你配置好的Retrofit对象)和Method(即你自定义接口中你说调用的那个方法的Method对象)两个参数,并通过method的getAnnotations、getGenericParameterTypes、getParameterAnnotations来分别为其成员属性初始化赋值。
继续看build方法:
public ServiceMethod build() {
//这里创建CallAdapter
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?");
}
//这里创建Converter
responseConverter = createResponseConverter();
for (Annotation annotation : methodAnnotations) {
//解析校验方法中的注解
parseMethodAnnotation(annotation);
}
......
return new ServiceMethod<>(this);
}
build方法中会创建CallAdapter和Converter实例(通过Retrofit中指定的CallFactory和ConverterFactory),校验方法上的注解和方法参数及参数注解。校验逻辑这里就跳过了,不难但是多,我们来重点看下CallAdapter和Converter的创建。
先看CallAdapter的创建
CallAdapter的创建
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);
}
//返回值类型为Void抛出异常
if (returnType == void.class) {
throw methodError("Service methods cannot return void.");
}
Annotation[] annotations = method.getAnnotations();
try {
//看这里!!看这里!!看这里!!
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);
}
}
createCallAdapter中首先对方法的返回值进行校验,首先校验是否有无法处理的类型:
//检查是否含有无法处理的类型
static boolean hasUnresolvableType(Type type) {
if (type instanceof Class<?>) {
return false;
}
//判断返回值是否是泛型参数类型
if (type instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) type;
for (Type typeArgument : parameterizedType.getActualTypeArguments()) {
//此处递归检查
if (hasUnresolvableType(typeArgument)) {
return true;
}
}
return false;
}
if (type instanceof GenericArrayType) {
return hasUnresolvableType(((GenericArrayType) type).getGenericComponentType());
}
//类型参数
if (type instanceof TypeVariable) {
return true;
}
//通配类型
if (type instanceof WildcardType) {
return true;
}
String className = type == null ? "null" : type.getClass().getName();
throw new IllegalArgumentException("Expected a Class, ParameterizedType, or "
+ "GenericArrayType, but <" + type + "> is of type " + className);
}
校验逻辑参考注释,hasUnresolvableType是一个递归方法,用于泛型层次比较深的情况。
其次返回值为void(无返回值)时也会抛出异常,经过以上两个检查后,最终调用retrofit.callAdapter(returnType, annotations),跟一下:
public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType,
Annotation[] annotations) {
checkNotNull(returnType, "returnType == null");
checkNotNull(annotations, "annotations == null");
//调用到这里时skipPast为null,因此start的值为0
int start = adapterFactories.indexOf(skipPast) + 1;
//遍历adapterFactories集合并调用get方法,如果不为null则返回
for (int i = start, count = adapterFactories.size(); i < count; i++) {
CallAdapter<?, ?> adapter = adapterFactories.get(i).get(returnType, annotations, this);
if (adapter != null) {
return adapter;
}
}
......
throw new IllegalArgumentException(builder.toString());
}
nextCallAdapter会从adapterFactories的首位开始遍历并调用get方法,当找到能够处理当前调用方法的CallAdapter后便停止遍历并返回该CallAdapter,如果未找到合适的CallAdapter(包括内置的CallAdapter),则抛出异常。
再看Converter的创建
Converter的创建
private Converter<ResponseBody, T> createResponseConverter() {
Annotation[] annotations = method.getAnnotations();
try {
//看这里!!看这里!!看这里!!
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);
}
}
直接看注释那里,继续跟!:
public <T> Converter<ResponseBody, T> nextResponseBodyConverter(
@Nullable Converter.Factory skipPast, Type type, Annotation[] annotations) {
checkNotNull(type, "type == null");
checkNotNull(annotations, "annotations == null");
//skipPast此时也为null,start的值为0
int start = converterFactories.indexOf(skipPast) + 1;
//遍历converterFactories,找到合适的(不为null)则返回
for (int i = start, count = converterFactories.size(); i < count; i++) {
Converter<ResponseBody, ?> converter =
converterFactories.get(i).responseBodyConverter(type, annotations, this);
if (converter != null) {
//noinspection unchecked
return (Converter<ResponseBody, T>) converter;
}
}
......
throw new IllegalArgumentException(builder.toString());
}
和nextCallAdapter方法很相似,从converterFactories中遍历寻找合适的Converter,一旦找到则终止循环并返回,如果找不到合适的Converter则抛出异常。在Retrofit.Builder的build方法中有提到build的时候converterFactories会被添加一个内置的Converter到首位置。这个Converter是BuiltInConverters,现在让我们来看一下BuiltInConverters这个类的定义:
final class BuiltInConverters extends Converter.Factory {
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
//如果返回结果类型泛型参数为ResponseBody
if (type == ResponseBody.class) {
return Utils.isAnnotationPresent(annotations, Streaming.class)
? StreamingResponseBodyConverter.INSTANCE
: BufferingResponseBodyConverter.INSTANCE;
}
//如果返回结果类型泛型参数为Void
if (type == Void.class) {
return VoidResponseBodyConverter.INSTANCE;
}
return null;
}
......
}
这里只给大家贴出了responseBodyConverter这个方法的代码,可以看到当自定义接口中的方法的返回值泛型参数类型为ResponseBody时,如果有Streaming注解修饰则返回StreamingResponseBodyConverter,否则返回BufferingResponseBodyConverter;如果返回值泛型参数类型为Void,则返回VoidResponseBodyConverter;上面都不满足则返回null。
上面是对
ServiceMethod<Object, Object> serviceMethod = (ServiceMethod<Object, Object>) loadServiceMethod(method);
这一行代码的跟踪和分析,现在回到invoke方法中最下面的部分继续看剩余两行代码:
//创建OkHttpCall对象
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
创建OkHttpCall对象
//利用CallAdapter将okHttpCall转换为指定的类型(默认为Call<Object>)
return serviceMethod.callAdapter.adapt(okHttpCall);
利用serviceMethod中的callAdapter的adapt方法将内置的OkHttpCall转换为指定的类型
第四步:通过Call对象发起请求
call.enqueue(object : Callback<MsgBean> {
override fun onFailure(call: Call<MsgBean>?, t: Throwable?) {
Log.i("wh", "onFailure")
}
override fun onResponse(call: Call<MsgBean>?, response: Response<MsgBean>?) {
Log.i("wh", "onResponse")
}
})
使用内置的Call对象(ExecutorCallbackCall)发起请求,前面有将,这里就不在复述了。