分析的源码版本是:retrofit 2.8.1
先看一个简单实例,其中的Call用liveData适配。从这个demo开始一步步进行源码分析
interface Api {
companion object {
fun getInstance(): Api {
return Retrofit.Builder()
.baseUrl("https://www.test.com/")
.client(OkHttpClient.Builder().build())
.addCallAdapterFactory(LiveDataCallAdapterFactory())
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(Api::class.java)
}
}
@GET("user/info")
fun getUserInfo(): LiveData<ApiResponse<UserVo>>
}
private fun loadData(){
val user = Api.getInstance().getUserInfo()
user.observe(this, Observer {
val user :UserVo? = it.data
})
}
一、流程分析
1.1 创建对象
从上面的demo图中可以看出Api实例化的过程很简单,重点在于最后两步的build()创建Retrofit对象的过程和create(Api::class.java)创建Api实例的过程,前面配置的过程简单,因此略过。
1.1.1 build()过程
/**
* 创建Retrofit实例对象
*/
public Retrofit build() {
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
//设置callFactory,若没有自己配置的话将采用默认的callFactory
//本例采用自定义的LiveDataCallAdapterFactory
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new OkHttpClient();
}
//根据平台选择执行者,Android这里会选择Android的执行者,默认是MainThreadExecutor
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
// 安全拷贝已设置的CallAdapter.Factory列表然后添加一个默认的CallAdapter.Factory
List<CallAdapter.Factory> callAdapterFactories = new ArrayList<> (this.callAdapterFactories);
callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));
// 拷贝已设置的和默认的Converter.Factory
List<Converter.Factory> converterFactories = new ArrayList<>(
1 + this.converterFactories.size() + platform.defaultConverterFactoriesSize());
converterFactories.add(new BuiltInConverters());
converterFactories.addAll(this.converterFactories);
converterFactories.addAll(platform.defaultConverterFactories());
//返回Retrofit实例,且为了安全converterFactories和callAdapterFactories被设置为不可变
return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
}
可以看出build的过程是对设置的CallAdapterFactory和ConverterFactory做统一安全措施
1.1.2 create()过程
create()返回一个service动态代理(本例中是返回Api类的动态代理),当调用getUserInfo()方法时会进入到InvocationHandler的invoke()方法中。
public <T> T create(final Class<T> service) {
validateServiceInterface(service);//检查service是否是有效的接口
//返回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 {
//proxy指代理对象,method是代理对象的方法,args是方法的参数
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);
}
});
}
在本例中,service指的是传入Api这个类,method就是getUserInfo()这个方法。其后通过动态代理创建类Api的实例化对象,重点在于最后的调用方法那行代码
先看下loadServiceMethod这个方法:
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;
}
这个方法就是返回一个ServiceMethod实例对象,跟进去看下ServiceMethod这个类的信息:
abstract class ServiceMethod<T> {
//解析注解
static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
//重点行①
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.");
}
//重点行②
return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
}
abstract @Nullable T invoke(Object[] args);
}
可以看出ServiceMethod类是个抽象类,且非常简单就只有一个解析注解的静态方法parseAnnotations()和一个invoke()方法,根据方法解析它的注解,本例中就是解析getUserInfo()方法的get注解,返回的是HttpServiceMethod这个抽象类,它继承自ServiceMethod,作用是将接口方法的调用调整为HTTP调用。
上面有两个重点行,重点行①是一个请求工厂类,这个类的作用是解析注解(包括方法注解及参数注解)封装成okhttp3.Request请求(包括url字符串拼接,获取其中的请求参数值等)。其中可以看到解析注解的关键方法:
重点行②的HttpServiceMethod.parseAnnotations()方法同样是解析注解,进去看下它与重点行①的解析有什么不同:
static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
Retrofit retrofit, Method method, RequestFactory requestFactory) {
... //省略
//创建CallAdapter实例
CallAdapter<ResponseT, ReturnT> callAdapter =
createCallAdapter(retrofit, method, adapterType, annotations);
Type responseType = callAdapter.responseType();
...//省略
//创建Converter实例
Converter<ResponseBody, ResponseT> responseConverter =
createResponseConverter(retrofit, method, responseType);
okhttp3.Call.Factory callFactory = retrofit.callFactory;
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()的作用主要就是根据方法注解创建CallAdapter和Converter的实例对象,也就是本例中的LiveDataCallAdapterFactory()和GsonConverterFactory()的实例对象。最后根据平台版本返回不同的对CallAdapter的封装类,最终会调用其中CallAdapter对象的的adapt()方法
回溯到1.1.2 create()过程的重点行:
return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
这个invoke()实际上最终会调用HttpServiceMethod类实例的invoke()方法:
@Override final @Nullable ReturnT invoke(Object[] args) {
Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory,
responseConverter);
return adapt(call, args);
}
可以看到这里实例化了一个OkHttpCall对象,传入了请求参数,调用了adapt()方法,实际上最后调用的是上面说的CallAdapter对象的的adapt()方法,其中会调用Call.enque()或者调用CAll.execute()方法发起网络请求,由于我们是自定义的LiveDataCallAdapter,所以会调用LiveDataCallAdapter对象的adapt()方法,简单来说,Create()过程做的主要工作就是解析注解封装成request请求和实例化callAdapter与responseConverter的过程。
1.2 网络请求
进入到LiveDataCallAdapter类中看看,会看到adapt()方法中实际上调用了call.enqueue()发起了异步网络请求,onResponse()中获得请求的返回信息后封装成LiveData数据返回给调用方
//将Retrofit的Call对象适配成LiveData
class LiveDataCallAdapter<T>(private val responseType: Type) : CallAdapter<T, LiveData<T>> {
override fun adapt(call: Call<T>): LiveData<T> {
return object : LiveData<T>() {
private val started = AtomicBoolean(false)
override fun onActive() {
super.onActive()
if (started.compareAndSet(false, true)) {//确保执行一次
call.enqueue(object : Callback<T> {
override fun onFailure(call: Call<T>, t: Throwable) {
val value = ApiResponse<T>(null, -1, t.message ?: "") as T
postValue(value)
}
override fun onResponse(call: Call<T>, response: Response<T>) {
postValue(response.body())
}
})
}
}
}
}
override fun responseType() = responseType
}
private fun loadData(){
val user = Api.getInstance().getUserInfo()
user.observe(this, Observer {
val user :UserVo? = it.data
})
}
然后通知liveData的观察者更新数据,最终在observe方法中拿到数据。至此一个网络请求流程就走通了。
二、总结
retrofit主要就是对OKhttp的封装,封装的重点在于对注解的丰富解析,对CallAdapter的扩展支持,对Converter的丰富支持。最终封装成简单易用的网络框架,实际上的网络请求还是通过okhttp进行的,相当于在其之上加了一层而已,只是这一层的封装特别香。