Retrofit流程极简解析
Retrofit流程极简解析
以SandwichDemo为例子来解析。github地址
创建Retrofit
private val retrofit: Retrofit = Retrofit.Builder()
.client(okHttpClient)
.baseUrl(
"https://gist.githubusercontent.com/skydoves/aa3bbbf495b0fa91db8a9e89f34e4873/raw/a1a13d37027e8920412da5f00f6a89c5a3dbfb9a/"
)
.addConverterFactory(GsonConverterFactory.create())
/* asynchronous supports */
// .addCallAdapterFactory(DataSourceCallAdapterFactory.create())
/* coroutines supports */
.addCallAdapterFactory(CoroutinesResponseCallAdapterFactory.create())
//.addCallAdapterFactory(CoroutinesDataSourceCallAdapterFactory.create())
.build()
创建接口类
val disneyService: DisneyCoroutinesService = retrofit.create(DisneyCoroutinesService::class.java)
获取接口返回的数据
val apiResponse:ApiResponse<List<Poster>> = disneyService.fetchDisneyPosterList()
就是这么简单,数据获取完成
细分流程解析
- 创建
Retrofit
。这里使用了创建者模式,通过Retrofit.Builder
来创建Retrfofit
实例,一般项目里都会做成单例 Builder().client(OkHttpClient client)
设置网络请求的最终调用者,这里和OkHttp
是绝配baseUrl(Url baseUrl)
设置baseUrl
链接addConverterFactory(Converter.Factory factory)
添加网络参数和返回类的转换器,例如Gson,Moshi
等addCallAdapterFactory(CallAdapter.Factory factory)
添加接口请求结果的转换器build()
方法中,会通过platform.defaultCallAdapterFactories(callbackExecutor)
来添加默认的CallAdapter.Factory
转换器和我们自定义的转换器。而ConvertorFactory
转换器,默认加入new BuiltInConverters()
和平台默认转换器platform.defaultConverterFactories()
以及我们自定义的转换器
- 创建
通过
Retrofit创建接口类
1.调用create(Class<T> 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);
}
args = args != null ? args : emptyArgs;
return platform.isDefaultMethod(method)
? platform.invokeDefaultMethod(method, service, proxy, args)
: loadServiceMethod(method).invoke(args);
}
});
这里就是通过动态代理来。动态代理的理论网上很多,可以自己搜索;简单说下,就是比如代理的接口类,调用它的方法时候,会进入到动态代理类里
InvocationHandler
的invoke()
中,这里参数有method
提供Method
的各种方法,args
参数提供方法的各个参数。这里就是完全代理了接口方法,来自己实现,这里思想多大,舞台就有多大。invoke
方法解析- 解析
loadServiceMethod(method).invoke(args)
。loadServiceMethod()
方法返回ServiceMethod
抽象类,实际是HttpServiceMethod
类。 - 核心方法
HttpServiceMethod.parseAnnotations
方法调用并返回HttpServiceMethod
类,这里是核心解析方法;上面的invoke(args)
方法最终是调用了HttpServiceMethod
类的invoke
方法,最终是调用如下:
@Override
final @Nullable ReturnT invoke(Object[] args) {
Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
return adapt(call, args);
}
这里记住这个类
OkHttpCall
3. 解析HttpServiceMethod<ResponseT, ReturnT>.parseAnnotations()
方法: 这里会通过RequestFactory
来解析参数和返回值,其中java if (Utils.getRawType(parameterType) == Continuation.class) { isKotlinSuspendFunction = true; return null; }
这个解析判断是否是suspend
函数。 这里会根据是否挂起函数来确定不同的返回值。 继续:根据是否是挂起函数,来获取对应的adapterType
,即类似Call<UserData>
里的UserData
类型,或者suspend
里UserData
返回值类型。CallAdapter<ResponseT, ReturnT> callAdapter =
createCallAdapter(retrofit, method, adapterType, annotations);
Type responseType = callAdapter.responseType();
这里通过返回类型,来匹配我们加入的
CallAdapter
来进行返回的Response
的包装或者逻辑处理Converter<ResponseBody, ResponseT> responseConverter =
createResponseConverter(retrofit, method, responseType);
这里通过
responseType
来获取我们添加的返回结果转换器,比如GsonFactory,MothiFactory
来 4.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);
}
这里会返回最终的各式各样的
HttpMethod
的实现类 如果非suspend
函数,则直接返回CallAdapter
这里,Java
代码非协程一般都是这种情况; 如果是suspend
函数且返回值为Response
类型的,则返回SuspendForResponse
其余的suspend
函数情况,则返回SuspendForBody
,kotlin+协程
里一般是这种情况 5. 分析CallAdapter
和SuspendForBody
的区别,最大区别,就是Suspend
会再adapt里自动调用OkHttp的请求接口方法并返回对应的Response
,而CallAdapter
则不会,而是需要使用者自己去调用。至此,简略版的Retrofit流程已经梳理完毕
我们自己可以自定义的部分:
ConverterFactory
,CallFactory
这里官方都给了默认的和常用的,例如Converter
转换类就有gson,guava,jackson,moshi,jaxb....
;而默认的CallFactory
,除了库里自带的默认的DefualtCallFactory
,还有官方写的库:guava,java8,rxjava,rxjava2,rxjava3,scala
,这里常用的是rxjava2,rxjava3
,还有例如我现在用的Sandwich
库里封装的CoroutinesResponseCallAdapterFactory
和kotlin
协程配合起来非常好用- 解析