Retrofit源码解析
本文简单介绍通过retrofit是怎样发起一个网络请求的。
1.基本使用
retrofit一般和okhttp配合使用
首先创建okhttpClient实例对象
val okHttpClient by lazy {
val build = OkHttpClient.Builder()
build.readTimeout(10000, TimeUnit.MILLISECONDS)
build.writeTimeout(10000, TimeUnit.MILLISECONDS)
build.connectTimeout(10000, TimeUnit.MILLISECONDS)
val httpLoggingInterceptor = HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY
}
build.addInterceptor(httpLoggingInterceptor)
build.build()
}
然后将okhttpClient实例对象配置到retrofit中
val retrofit by lazy {
Retrofit.Builder()
.client(okHttpClient)
.baseUrl("https://www.wanandroid.com")
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build()
}
创建ApiService
interface ApiService {
@GET
fun login(@QueryName username: String, @QueryName password: String): Call<Boolean>
}
然后通过retrofit是对象调用create方法,创建ApiService实例对象,并发起网络请求
val username="abc"
val password="123"
val apiService = NetWorkHelper.retrofit.create(ApiService::class.java)
apiService.login(username,password).enqueue(object : Callback<Boolean> {
override fun onResponse(call: Call<Boolean>, response: Response<Boolean>) {
TODO("Not yet implemented")
}
override fun onFailure(call: Call<Boolean>, t: Throwable) {
TODO("Not yet implemented")
}
})
2.原理解析
1.创建retrofit实例对象,通过建造者模式
回顾代码
val retrofit by lazy {
Retrofit.Builder()
.client(okHttpClient)
.baseUrl("https://www.wanandroid.com")
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build()
}
看一下类结构
可以看到Builder类提供了一系列方法用来提供retrofit所需要的参数
先看setClient方法
/**
* The HTTP client used for requests.
* <p>
* This is a convenience method for calling {@link #callFactory}.
*/
public Builder client(OkHttpClient client) {
return callFactory(Objects.requireNonNull(client, "client == null"));
}
/**
* Specify a custom call factory for creating {@link Call} instances.
* <p>
* Note: Calling {@link #client} automatically sets this value.
*/
public Builder callFactory(okhttp3.Call.Factory factory) {
this.callFactory = Objects.requireNonNull(factory, "factory == null");
return this;
}
因为okhttpClient类实现了Okttp3.Call.Factory接口,所以将穿进来的okhttpClient对象向上转型为callFactory
然后看addConvertFactory和addCallAdapterFactory
/** Add converter factory for serialization and deserialization of objects. */
public Builder addConverterFactory(Converter.Factory factory) {
converterFactories.add(Objects.requireNonNull(factory, "factory == null"));
return this;
}
/**
* Add a call adapter factory for supporting service method return types other than {@link
* Call}.
*/
public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
callAdapterFactories.add(Objects.requireNonNull(factory, "factory == null"));
return this;
}
可以看到将传进来的factory放到了factory集合里面
private final List<Converter.Factory> converterFactories = new ArrayList<>();
private final List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>();
最后看build()方法
public Retrofit build() {
// 注释1:如果baseUrl==null 抛出异常
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
okhttp3.Call.Factory callFactory = this.callFactory;
// 注释2:如果callFactory==null 创建okhttpClient对象
if (callFactory == null) {
callFactory = new OkHttpClient();
}
Executor callbackExecutor = this.callbackExecutor;
// 注释3 如果callbackExecutor==null 则用平台默认的Executor
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
// Make a defensive copy of the adapters and add the default Call adapter.
// 注释4:先copy设置的callAdapterFactories再添加平台默认的callAdapterFactories
List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));
// Make a defensive copy of the converters.
// 注释5:创建了一个 1 + this.converterFactories.size() + platform.defaultConverterFactoriesSize() 的数组
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.
// 注释6:然后添加各种converterFactories
converterFactories.add(new BuiltInConverters());
converterFactories.addAll(this.converterFactories);
converterFactories.addAll(platform.defaultConverterFactories());
// 注释7:创建retrofit对象
return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
}
retrofit构造方法
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;
}
可以看到就是各种赋值
2.通过代理模式,动态代理的方式创建apiService的代理对象
val apiService = NetWorkHelper.retrofit.create(ApiService::class.java)
调用create方法
public <T> T create(final Class<T> service) {
validateServiceInterface(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 @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);
}
return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
}
});
}
有关动态代理的详细知识可百度查阅
概括来说
Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h)
可以生成具体类的代理类
参数1:是生成代理类要声明的类加载器
参数2:是代理类要实现的接口
参数3:是实现InvocationHandler接口的实现类,通过代理类调用的接口方法都会通过InvocationHandler接口的invoke方法转发
invoke(Object proxy, Method method, Object[] args)方法中的三个参数
参数1:代理类实例对象
参数2:调用的方法实例对象
参数3:调用的方法参数
3.通过代理对象调用方法
val apiServicePoxy = NetWorkHelper.retrofit.create(ApiService::class.java)
apiService.login(username,password).enqueue(object : Callback<Boolean> {
override fun onResponse(call: Call<Boolean>, response: Response<Boolean>) {
TODO("Not yet implemented")
}
override fun onFailure(call: Call<Boolean>, t: Throwable) {
TODO("Not yet implemented")
}
})
这里生成了apiServicePoxy代理对象,并调用login方法,方法会执行invoke方法,看看invoke方法中做了什么工作
new InvocationHandler() {
// 注释1:获取平台实例对象
private final Platform platform = Platform.get();
// 注释2:创建了参数数组
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.
// 获取该方法所在类是否是Object.class,如果是则调用自身方法
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
// 注释3:加载方法并通过调用invoke方法
return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
}
}
看一下loadServiceMethod(method)方法做了什么
// serviceMethodCache 是一个ConcurrentHashMap,以Method为key,以ServiceMethod为value
private final Map<Method, ServiceMethod<?>> serviceMethodCache = new ConcurrentHashMap<>();
ServiceMethod<?> loadServiceMethod(Method method) {
// 注释1:先从缓存中获取
ServiceMethod<?> result = serviceMethodCache.get(method);
if (result != null) return result;
// 同步锁
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
// 注释2:获取不到再解析注解
result = ServiceMethod.parseAnnotations(this, method);
// 然后存储在 serviceMethodCache中
serviceMethodCache.put(method, result);
}
}
return result;
}
第一次result肯定为null,会走 ServiceMethod.parseAnnotations(this, method);方法
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);
}
看代码
static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
Retrofit retrofit, Method method, RequestFactory requestFactory) {
boolean isKotlinSuspendFunction = requestFactory.isKotlinSuspendFunction;
boolean continuationWantsResponse = false;
boolean continuationBodyNullable = false;
Annotation[] annotations = method.getAnnotations();
Type adapterType;
// -----------省略kotlin相关代码-----------
// 注释1:这里获取方法的返回类型
adapterType = method.getGenericReturnType();
// -----------省略kotlin相关代码-----------
// 注释2:创建callAdapter,这里的CallAdapter最终会调用DefaultCallAdapterFactory的get方法
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.");
}
// 注释3:创建responseConverter
Converter<ResponseBody, ResponseT> responseConverter =
createResponseConverter(retrofit, method, responseType);
okhttp3.Call.Factory callFactory = retrofit.callFactory;
// -----------省略kotlin相关代码-----------
// 注释4:创建CallAdapter这个CallAdapter是对注释2创建的CallAdapter的包装
return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
// -----------省略kotlin相关代码-----------
}
注释2:看一下DefaultCallAdapterFactory中的get方法
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
if (getRawType(returnType) != Call.class) {
return null;
} else if (!(returnType instanceof ParameterizedType)) {
throw new IllegalArgumentException("Call return type must be parameterized as Call<Foo> or Call<? extends Foo>");
} else {
final Type responseType = Utils.getParameterUpperBound(0, (ParameterizedType)returnType);
final Executor executor = Utils.isAnnotationPresent(annotations, SkipCallbackExecutor.class) ? null : this.callbackExecutor;
return new CallAdapter<Object, Call<?>>() {
public Type responseType() {
return responseType;
}
public Call<Object> adapt(Call<Object> call) {
return (Call)(executor == null ? call : new DefaultCallAdapterFactory.ExecutorCallbackCall(executor, call));
}
};
}
}
可以看到最终创建了CallAdapter的匿名内部类返回
注意注释4: // 注释4:创建CallAdapter这个CallAdapter是对注释2创建的CallAdapter的包装
看代码:
// 注释4:调用invoke方法
@Override final @Nullable ReturnT invoke(Object[] args) {
// 注释5:创建call对象
Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
// 注释6:调用adapt方法
return adapt(call, args);
}
protected abstract @Nullable ReturnT adapt(Call<ResponseT> call, Object[] args);
// 注释1:继承了HttpServiceMethod的CallAdapter
static final class CallAdapted<ResponseT, ReturnT> extends HttpServiceMethod<ResponseT, ReturnT> {
private final CallAdapter<ResponseT, ReturnT> callAdapter;
// 注释2:构造方法,注意传进来的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) {
// 注释3:实际调用了传进来的callAdapter的adapt方法
return callAdapter.adapt(call);
}
}
然后我们获取到了CallAdapter实例对象,注意该实例对象是HttpServiceMethod的静态内部类对象,这里回到
loadServiceMethod(method).invoke(args != null ? args : emptyArgs)
可以看到回调用invoke方法,也就是注释4
最终的执行过程是注释4===>注释5===>注释6===>注释3
看一下注释3中做了什么,这里会调用DefaultCallAdapterFactory中CallAdapter的adapt方法
public Call<Object> adapt(Call<Object> call) {
return (Call)(executor == null ? call : new DefaultCallAdapterFactory.ExecutorCallbackCall(executor, call));
}
executor是开始通过建造者模式创建retrofit对象时创建的
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
看一下 platform.defaultCallbackExecutor();
@Nullable Executor defaultCallbackExecutor() {
return null;
}
返回null,那么会执行new DefaultCallAdapterFactory.ExecutorCallbackCall(executor, call))
看一下做了什么
原来这里的ExecutorCallbackCall方法实现了retrofit的call接口,然后返回了,这里我们就得到了retrofit的call对象,就可以调用同步execute方法和equeue方法了,可以看到,最终是通过我们传进来的okhttpCall进行网络请求的。