Retrofit 全面解析
A type-safe HTTP client for Android and Java
源码分析版本:implementation 'com.squareup.retrofit2:retrofit:2.9.0'
Retrofit的使用
关于Retrofit的使用,这里就不再多于的讲解了,相信只要是做Android开发的都会使用Retrofit
https://square.github.io/retrofit/
最简单的使用方式如下:
interface GitHubService {
@GET("users/{user}/repos")
fun listRepos(@Path("user") user:String?):Call<List<Repo>>
}
val retrofit = Retrofit.Builder()
.baseUrl("https://api.github.com/")
.addConverterFactory(GsonConverterFactory.create()) //gson的转换工厂
.build()
retrofit.create(GitHubService::class.java).listRepos("octocat")
.enqueue(object :Callback<List<Repo>>{
override fun onResponse(call: Call<List<Repo>>, response: Response<List<Repo>>) {
println(response.body()?.size)
}
override fun onFailure(call: Call<List<Repo>>, t: Throwable) {
TODO("Not yet implemented")
}
})
看源码的思路,专注于一条线路,直到看懂这条线路。
下面我们先专注于create
方法这条路线A,然后是enqueue
这条路线B.
从Create方法分析
下面这段代码,通过Builder模式构建Retrofit实例
val retrofit = Retrofit.Builder()
.baseUrl("https://api.github.com/")
.addConverterFactory(GsonConverterFactory.create()) //gson的转换工厂
.build()
retrofit.create()
方法进行初始化代码如下:
通过Java的动态代理方式,对传递过来的Class代理方法,注意Class必须是接口,Java中的动态代理只能代理接口。
我们首先看第一步validateServiceInterface
方法干了什么?
public <T> T create(final Class<T> service) {
//1. 进行初始化验证service接口 先看一下这个方法
validateServiceInterface(service);
//2. 返回代理对象
return (T)
//使用java提供的动态代理
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);
}
});
}
validateServiceInterface
主要作用初始化的时候进行验证,验证service class是否使用正确:
private void validateServiceInterface(Class<?> service) {
//这个class必须是一个接口,如果不是接口就会报错
if (!service.isInterface()) {
throw new IllegalArgumentException("API declarations must be interfaces.");
}
//将接口加入到队列中
Deque<Class<?>> check = new ArrayDeque<>(1);
check.add(service);
while (!check.isEmpty()) {
//从队列中取出接口类
Class<?> candidate = check.removeFirst();
//class 接口类 不能有泛型 如:GithubService<T> 会报错
if (candidate.getTypeParameters().length != 0) {
StringBuilder message =
new StringBuilder("Type parameters are unsupported on ").append(candidate.getName());
if (candidate != service) {
message.append(" which is an interface of ").append(service.getName());
}
throw new IllegalArgumentException(message.toString());
}
//判断接口 是否还有继承 如果有继续循环
Collections.addAll(check, candidate.getInterfaces());
}
// 开关,validateEagerly 开发和正式 能够快速验证
if (validateEagerly) {
Platform platform = Platform.get();
for (Method method : service.getDeclaredMethods()) {
//过滤接口的默认方法和静态方法
if (!platform.isDefaultMethod(method) && !Modifier.isStatic(method.getModifiers())) {
//验证和加载接口类的方法
loadServiceMethod(method);
}
}
}
}
其实validateEagerly
主要用来在初始化的时候进行验证接口中的所有方法配置,一般在开发阶段进行设置为true,Retrofit给出的解释如下:
/**
* When calling {@link #create} on the resulting {@link Retrofit} instance, eagerly validate the
* configuration of all methods in the supplied interface.
当在结果{@link Retrofit}实例上调用{@link #create}时,急切地验证提供的接口中所有方法的配置。
*/
public Builder validateEagerly(boolean validateEagerly) {
this.validateEagerly = validateEagerly;
return this;
}
在初始化验证通过之后,会通过Java中的动态代理模式,生成代理对象。
动态代理
Java中的动态代理,通过Proxy生成接口的代理对象,当调用代理对象的方法的时候就会调用invoke方法。这也是Retrofit的核心的入口。
return (T)
//使用java提供的动态代理
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.
// 如果方式是在Object类中的方法,直接调用
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
args = args != null ? args : emptyArgs;
//platform 做兼容处理
return platform.isDefaultMethod(method) //考虑java8的兼容问题
//如果是默认方法 直接调用默认方法
? platform.invokeDefaultMethod(method, service, proxy, args)
: loadServiceMethod(method).invoke(args);//代理接口的方法
}
});
其实动态代理的原理非常简单,实际上等价于下面的代码:主要去关注invoke
回调方法中
class ProxyGitHubService : GitHubService {
val invocationHandler:InvocationHandler = InvocationHandler(object : (Any, Method, Array<Any>) -> Any{
override fun invoke(p1: Any, p2: Method, p3: Array<Any>): Any {
// 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);
}
})
override fun listRepos(user: String?): Call<List<Repo>> {
val method = GitHubService::class.java.getDeclaredMethod("listRepos",String::class.java)
return invocationHandler.invoke(this,method,user)
}
}
最终核心的方法就是loadServiceMethod
方法,最终调用了invoke()
方法。下面来看loadServiceMethod
做了什么?
loadServiceMethod
loadServiceMethod代码如下:从Map集合获取ServiceMethod
并返回,Retrifit做了缓存处理,下一次在调用直接从缓存中获取。这么这个ServiceMethod类有什么作用呢?
ServiceMethod<?> loadServiceMethod(Method method) {
//获取缓存的取出来,serviceMethodCache就是一个Map集合
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类,是一个抽象类,invoke方法并没有实现,可以看到通过parseAnnotations方法返回了ServiceMethod类的实例对象,我们找到ServiceMethod
的实现类HttpServiceMethod
类。
这里我们先把关注点放到invoke方法上,
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);
}
HttpServiceMethod
我们先看invoke方法的实现:
@Override
final @Nullable ReturnT invoke(Object[] args) {
Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
return adapt(call, args);
}
从invoke方法中可以看到有两条线路:OkHttpCall
以及adapt
. 通过源码线路分析图如下,这两条线路我们先看OkHttpCall这条线路C。
线路C -> OkHttpCall
可以看到OkHttpCall实现了Call接口,Call接口是否很熟悉,在我们使用Retrofit的使用,接口的方法会返回一个call
interface GitHubService {
@GET("users/{user}/repos")
fun listRepos(@Path("user") user:String?):Call<List<Repo>>
}
那也就是说,OkHttpCall实现了enqueue()
方法。代码如下:
@Override
public void enqueue(final Callback<T> callback) {
.........
//okhttp的call实例
okhttp3.Call call;
Throwable failure;
synchronized (this) {
..........
executed = true;
call = rawCall;
failure = creationFailure;
if (call == null && failure == null) {
try {
call = rawCall = createRawCall();
} catch (Throwable t) {
throwIfFatal(t);
failure = creationFailure = t;
}
}
}
.......
// 最终调用了okhttp的enqueue方法
call.enqueue(
new okhttp3.Callback() {
@Override
public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
Response<T> response;
try {
//解析返回结果
response = parseResponse(rawResponse);
} catch (Throwable e) {
throwIfFatal(e);
callFailure(e);
return;
}
.....
}
@Override
public void onFailure(okhttp3.Call call, IOException e) {
callFailure(e);
}
private void callFailure(Throwable e) {
.......
}
});
}
通过enqueue我们又发现了两条新的线路:createRawCall()
方法(创建okhttp的call对象)以及parseResponse()
方法(解析返回值)。
createRawCall
首先分析线路E如何创建okhttp.call的对象实例的。如下代码主要通过callFactory和requestFactory进行创建的,在创建OkHttpCall实例的时候传递进来的。
private okhttp3.Call createRawCall() throws IOException {
okhttp3.Call call = callFactory.newCall(requestFactory.create(args));
if (call == null) {
throw new NullPointerException("Call.Factory returned null.");
}
return call;
}
OkHttpCall(
RequestFactory requestFactory,
Object[] args,
okhttp3.Call.Factory callFactory,
Converter<ResponseBody, T> responseConverter) {
this.requestFactory = requestFactory;
this.args = args;
this.callFactory = callFactory;
this.responseConverter = responseConverter;
}
我们沿着链路向上寻找.此时线路图如下:
查找流程:HttpServiceMethod.invoke -> HttpServiceMethod.parseAnnotations()
如下代码:callFactory和requestFactory是由外部传递进来的,继续向上查找
static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
Retrofit retrofit, Method method, RequestFactory requestFactory) {
......
okhttp3.Call.Factory callFactory = retrofit.callFactory;
if (!isKotlinSuspendFunction) {
return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
}
.....
}
代码如下:我们看到了RequestFactory,终于找到他了,进去看看干了些啥。
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);
}
}
RequestFactory: 可以看到主要是处理接口类service.class的方法的注解的
RequestFactory build() {
for (Annotation annotation : methodAnnotations) {
parseMethodAnnotation(annotation);
}
....
}
处理完成之后会得到以下的值
我们回调线路E
在createRawCall()方法中调用了requestFactory.create()
方法。
private okhttp3.Call createRawCall() throws IOException {
okhttp3.Call call = callFactory.newCall(requestFactory.create(args));
if (call == null) {
throw new NullPointerException("Call.Factory returned null.");
}
return call;
}
requestFactory.create() 代码如下:最终就是得到了okhttp3.request这个RequestFactory其实就是拼接请求的
okhttp3.Request create(Object[] args) throws IOException {
@SuppressWarnings("unchecked") // It is an error to invoke a method with the wrong arg types.
ParameterHandler<Object>[] handlers = (ParameterHandler<Object>[]) parameterHandlers;
int argumentCount = args.length;
.......
RequestBuilder requestBuilder =
new RequestBuilder(
httpMethod,
baseUrl,
relativeUrl,
headers,
contentType,
hasBody,
isFormEncoded,
isMultipart);
if (isKotlinSuspendFunction) {
// The Continuation is the last parameter and the handlers array contains null at that index.
argumentCount--;
}
List<Object> argumentList = new ArrayList<>(argumentCount);
for (int p = 0; p < argumentCount; p++) {
argumentList.add(args[p]);
handlers[p].apply(requestBuilder, args[p]);
}
return requestBuilder.get().tag(Invocation.class, new Invocation(method, argumentList)).build();
}
那么线路E就理清楚了,其实就是okhttpclient.newCall(request)。这不就是okhttp的使用的api吗。
OK,requestFactory我们已经清楚了,其实就是对service class接口的方法中的注解处理,判断是get和post等等,然后返回okhttp3.request.
下面我们看callFactory: 从代码中可以看出是从retrofit.callFactory获取的,从build方法可以看到其实就是okHttpClient,我们也可以自己进行设置okHttpClient
retrofit.callFactory
public Retrofit build() {
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new OkHttpClient();
}
....
}
我们再看一下梳理的线路:这样看会非常清晰的流程
parseResponse
下面我们在看parseResponse线路F是如何执行的。代码如下(在OkHttpCall类中):最终通过responseConverter
的convert
方法处理的
Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
ResponseBody rawBody = rawResponse.body();
//.......
ExceptionCatchingResponseBody catchingBody = new ExceptionCatchingResponseBody(rawBody);
try {
T body = responseConverter.convert(catchingBody);
return Response.success(body, rawResponse);
} catch (RuntimeException e) {
// If the underlying source threw an exception, propagate that rather than indicating it was
// a runtime exception.
catchingBody.throwIfCaught();
throw e;
}
}
//responseConverter 同样也是在OkHttpCall的构造方法中创建的
OkHttpCall(
RequestFactory requestFactory,
Object[] args,
okhttp3.Call.Factory callFactory,
Converter<ResponseBody, T> responseConverter) {
this.requestFactory = requestFactory;
this.args = args;
this.callFactory = callFactory;
this.responseConverter = responseConverter;
}
所以我们得继续向上寻找:在HttpServiceMethod
的parseAnnotations
方法中返回了responseConverter
static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
Retrofit retrofit, Method method, RequestFactory requestFactory) {
.........
Converter<ResponseBody, ResponseT> responseConverter =
createResponseConverter(retrofit, method, responseType);
okhttp3.Call.Factory callFactory = retrofit.callFactory;
if (!isKotlinSuspendFunction) {
return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
}
.....
我们来看一下createResponseConverter
方法,调用了retrofit.responseBodyConverter
private static <ResponseT> Converter<ResponseBody, ResponseT> createResponseConverter(
Retrofit retrofit, Method method, Type responseType) {
Annotation[] annotations = method.getAnnotations();
try {
return retrofit.responseBodyConverter(responseType, annotations);
} catch (RuntimeException e) { // Wide exception range because factories are user code.
throw methodError(method, e, "Unable to create converter for %s", responseType);
}
}
代码如下:其实就是去遍历converterFactories集合,这个集合存储着Converter
,下面我们去找从哪里添加的Converter
public <T> Converter<ResponseBody, T> responseBodyConverter(Type type, Annotation[] annotations) {
return nextResponseBodyConverter(null, type, annotations);
}
.......
public <T> Converter<ResponseBody, T> nextResponseBodyConverter(
@Nullable Converter.Factory skipPast, Type type, Annotation[] annotations) {
.....
int start = converterFactories.indexOf(skipPast) + 1;
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;
}
}
}
找到了在Builder中,有一个设置的方法addConverterFactory
/** Add converter factory for serialization and deserialization of objects. */
public Builder addConverterFactory(Converter.Factory factory) {
converterFactories.add(Objects.requireNonNull(factory, "factory == null"));
return this;
}
不知道大家是否还记得在开始的时候使用Retorfit的进行初始化,看到了没就是它addConverterFactory。我们添加了GsonConverterFactory就是通过gson去解析json数据转换为设置的javabean类。
val retrofit = Retrofit.Builder()
.baseUrl("https://api.github.com/")
.addConverterFactory(GsonConverterFactory.create()) //gson的转换工厂
.build()
OK,那么OkHttpCall的整个流程思路都梳理清晰了。我们再看一下流程图。其实我们从Retrofit的源码中可以学习到很多设计模式,学习优秀的代码
线路D -> adapt
我们继续回到HttpServiceMethod的invoke方法,去看adapt的具体实现。
@Override
final @Nullable ReturnT invoke(Object[] args) {
Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
return adapt(call, args);
}
如下代码:adapt是HttpServiceMethod的抽象方法
protected abstract @Nullable ReturnT adapt(Call<ResponseT> call, Object[] args);
那么它是如何实现的呢?我们继续回到parseAnnotations
这个方法返回了HttpServerMethod
的实例,那么一定实现了adapt
抽象方法的。
if (!isKotlinSuspendFunction) { //这里主要判断 方法是否使用了kotlin的suspend标记,这里我们先不关心suspend是干什么的,一般是不用suspend的那么就会返回一个CallAdapted
return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
}
....
我们接着来看CallAdapted的实现, en….. 很奇怪,callAdapter是从外部传递进来的,通过外部传递进来的callAdapter调用adapt方法
static final class CallAdapted<ResponseT, ReturnT> extends HttpServiceMethod<ResponseT, ReturnT> {
private final CallAdapter<ResponseT, ReturnT> 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) {
return callAdapter.adapt(call);
}
}
我们还得要继续回到parseAnnotations
可以看到这样的一段代码:
....
CallAdapter<ResponseT, ReturnT> callAdapter =
createCallAdapter(retrofit, method, adapterType, annotations);
....
if (!isKotlinSuspendFunction) {
return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
}
....
原来调用了createCallAdapter方法:诶…. 这个方法返回的callAdapter是由retrofit的callAdapter返回的。
private static <ResponseT, ReturnT> CallAdapter<ResponseT, ReturnT> createCallAdapter(
Retrofit retrofit, Method method, Type returnType, Annotation[] annotations) {
try {
//noinspection unchecked
return (CallAdapter<ResponseT, ReturnT>) retrofit.callAdapter(returnType, annotations);
} catch (RuntimeException e) { // Wide exception range because factories are user code.
throw methodError(method, e, "Unable to create call adapter for %s", returnType);
}
}
继续回到Retrofit,代码如下:其实和上述讲的responseBodyConverter
类似可以由使用者自己定义进行设置,我们可以看到在nextCallAdapter只要遍历的adapter不等于null就会返回终止遍历,也就是说Retrofit只能有一个CallAdapter,Retrofit肯定有一个默认的CallAdapter因为我们在使用的时候并没有设置它
public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) {
return nextCallAdapter(null, returnType, annotations);
}
public CallAdapter<?, ?> nextCallAdapter(
@Nullable CallAdapter.Factory skipPast, Type returnType, Annotation[] annotations) {
.....
int start = callAdapterFactories.indexOf(skipPast) + 1;
for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
// 获取CallAdapter
CallAdapter<?, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this);
if (adapter != null) {
return adapter;
}
}
......
}
我们去Retrofit.Builder.build()方法中查看,代码如下:
public Retrofit build() {
.......
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
// 获取线程池 注意platform代表的是平台,一般分为Android和Java
callbackExecutor = platform.defaultCallbackExecutor();
}
List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));
.......
}
我们进入Platform的defaultCallAdapterFactories
// 获取platform 根据jvm的name不同进行获取
private static Platform findPlatform() {
return "Dalvik".equals(System.getProperty("java.vm.name"))
? new Android() //
: new Platform(true);
}
List<? extends CallAdapter.Factory> defaultCallAdapterFactories(
@Nullable Executor callbackExecutor) {
DefaultCallAdapterFactory executorFactory = new DefaultCallAdapterFactory(callbackExecutor);
return hasJava8Types
? asList(CompletableFutureCallAdapterFactory.INSTANCE, executorFactory)
: singletonList(executorFactory);
}
// defaultCallbackExecutor的线程池的执行是在主线程中执行的
static final class Android extends Platform {
Android() {
super(Build.VERSION.SDK_INT >= 24);
}
@Override
public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
@Nullable
@Override
Object invokeDefaultMethod(
Method method, Class<?> declaringClass, Object object, Object... args) throws Throwable {
if (Build.VERSION.SDK_INT < 26) {
throw new UnsupportedOperationException(
"Calling default methods on API 24 and 25 is not supported");
}
return super.invokeDefaultMethod(method, declaringClass, object, args);
}
static final class MainThreadExecutor implements Executor {
// 主线程中的Handler
private final Handler handler = new Handler(Looper.getMainLooper());
@Override
public void execute(Runnable r) {
handler.post(r);
}
}
}
再看一下,DefaultCallAdapterFactory,如何实现CallAdapter的。
final class DefaultCallAdapterFactory extends CallAdapter.Factory {
private final @Nullable Executor callbackExecutor;
DefaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
this.callbackExecutor = callbackExecutor;
}
@Override
public @Nullable CallAdapter<?, ?> get(
Type returnType, Annotation[] annotations, Retrofit retrofit) {
//首先判断service 接口方法返回的是Call,如果不是则返回为null 继续循环匹配
if (getRawType(returnType) != Call.class) {
return null;
}
........
// 返回CallAdapter的实例
return new CallAdapter<Object, Call<?>>() {
@Override
public Type responseType() {
return responseType;
}
@Override
public Call<Object> adapt(Call<Object> call) {
return executor == null ? call : new ExecutorCallbackCall<>(executor, call);
}
};
}
// 对Call包装
static final class ExecutorCallbackCall<T> implements Call<T> {
final Executor callbackExecutor;
final Call<T> delegate;
// 传递过来一个线程池和delegateCall
ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) {
this.callbackExecutor = callbackExecutor;
this.delegate = delegate;
}
@Override
public void enqueue(final Callback<T> callback) {
.....
delegate.enqueue(
new Callback<T>() {
@Override
public void onResponse(Call<T> call, final Response<T> response) {
//进行线程切换,将回调在主线程中执行
callbackExecutor.execute(
() -> {
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);
}
});
}
.......
});
}
}
其实默认的CallAdapter就做了一件事,就是线程切换,在主线程中进行一个回调。
那么如何自定义CallAdapter呢?我们知道默认的Retrofit的接口方法的返回值为Call,加入我们要使用RxJava,如何适配?
@GET("users/{user}/repos")
fun listReposRx(@Path("user") user:String?):Single<List<Repo>>
val retrofit = Retrofit.Builder()
.baseUrl("https://api.github.com/")
.addConverterFactory(GsonConverterFactory.create()) //gson的转换工厂
.addCallAdapterFactory(RxJava3CallAdapterFactory.create())// 添加RxJava支持
.build()
retrofit.create(GitHubService::class.java).listReposRx("octocat")
.subscribe()
那么RxJavaCallAdapter是如何匹配RxJava的返回类型的呢?
@Override
public @Nullable CallAdapter<?, ?> get(
Type returnType, Annotation[] annotations, Retrofit retrofit) {
Class<?> rawType = getRawType(returnType);
//根据他有的返回类型进行匹配的
if (rawType == Completable.class) {
// Completable is not parameterized (which is what the rest of this method deals with) so it
// can only be created with a single configuration.
return new RxJava3CallAdapter(
Void.class, scheduler, isAsync, false, true, false, false, false, true);
}
boolean isFlowable = rawType == Flowable.class;
boolean isSingle = rawType == Single.class;//我们上述的例子中就使用的是Single
boolean isMaybe = rawType == Maybe.class;
if (rawType != Observable.class && !isFlowable && !isSingle && !isMaybe) {
return null;
}
.......
}
Retrofit 如何确认多个返回类型不一致,该使用那个Adapter呢? 通过调用nextCallAdapter 去寻找目标的Adapter
//Retrofit.java
public CallAdapter<?, ?> nextCallAdapter(
@Nullable CallAdapter.Factory skipPast, Type returnType, Annotation[] annotations) {
Objects.requireNonNull(returnType, "returnType == null");
Objects.requireNonNull(annotations, "annotations == null");
int start = callAdapterFactories.indexOf(skipPast) + 1;
for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
CallAdapter<?, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this);
if (adapter != null) {
return adapter;
}
}
...
}
在RxJava的Adapter中如何进行类型判断的:通过get方法判断返回值的类型是不是特有的RxJava的类型,如果不是返回null。
OK,那么Retrofit的完整的流程如下,通过线路的方式理清源码。