上期 Retrofit 源码解读,这期查看下如何支持 Kotlin 协程的。(上篇的 retrofit 版本 可能与这篇不同)
例子还是最简单的标准例子,定义 interface 接口,这里就不贴多余代码了
@GET("/app/v1/commodity")
suspend fun commodity(
@Query("pageNo") pageNo: Int,
@Query("pageSize") pageSize: Int
): BaseResult<Pager<CommodityPO>>
第一步先将 kotlin 代码转成 Java 代码查看 suspend 方法有何不同,以下是转换后的代码
@GET("/app/v1/commodity")
@Nullable
Object commodity(@Query("pageNo") int var1, @Query("pageSize") int var2, @NotNull Continuation var3);
可以看到多出一个 Continuation 的参数,此为协程相关的 kotlin.coroutines.Continuation 接口示例。注意这里 BaseResult<Pager<CommodityPO>> 被转换成 Object 了。
@SinceKotlin("1.3")
public interface Continuation<in T> {
public val context: CoroutineContext
public fun resumeWith(result: Result<T>)
}
了解协程的应该已经猜出答案了,难道是 Continuation 类型的 var3 直接回调嘛,答案确实是。但我们重点是去探究下 Retrofit 如何架构的,所以跟进源码去查看一番。我们直接转到 动态代理的 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 {
//...
args = args != null ? args : emptyArgs;
return platform.isDefaultMethod(method)
? platform.invokeDefaultMethod(method, service, proxy, args)
: loadServiceMethod(method).invoke(args);
}
});
}
同理,会调用 loadServiceMethod 方法,将 Method 传入,去获取 ServiceMethod 对象。
ServiceMethod<?> loadServiceMethod(Method method) {
//...
result = ServiceMethod.parseAnnotations(this, method);
//...
return result;
}
一个缓存标准实现后,进入parseAnn

最低0.47元/天 解锁文章
456

被折叠的 条评论
为什么被折叠?



