前言
Retrofit适配器,通俗的理解就是我们写的Service接口中的返回值类型适配,常用的类型有Call,Observable。
Retrofit的准备工作
理解适配器前,我们先来了解一下retrofit的前期准备工作。
retrofit = new Retrofit.Builder()
.client(client)//okhttpclient
.validateEagerly(false)//是否需要进行懒加载
//添加Rxjava适配器
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
//添加Gson转换器,将字符流转换成javaBean
.addConverterFactory(GsonConverterFactory.create())
.baseUrl("https://xxx.com")
.build();
分析之前先梳理一下retrofit的创建过程。这边的代码很简单,我就不进行过多叙述了。
Retrofit变量解释
//用于存储service方法中的注解值,和返回值等信息(一个method对应一个ServiceMethod)
private final Map<Method, ServiceMethod<?, ?>> serviceMethodCache = new ConcurrentHashMap<>();
final okhttp3.Call.Factory callFactory;//传入的okhttpclient
final HttpUrl baseUrl;
final List<Converter.Factory> converterFactories;
final List<CallAdapter.Factory> callAdapterFactories;
final @Nullable Executor callbackExecutor;//回调的线程池默认主线程
final boolean validateEagerly;//是否懒加载
Retrofit.Build::build()
public Retrofit build () {
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new OkHttpClient();
}
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
//获取对应的平台 1
callbackExecutor = platform.defaultCallbackExecutor();
}
// Make a defensive copy of the adapters and add the default Call adapter.
List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
//往callAdapter中加入默认适配器工厂
callAdapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
// Make a defensive copy of the converters.
List<Converter.Factory> converterFactories =
new ArrayList<>(1 + this.converterFactories.size());
// Add the built-in converter factory first. This prevents overriding its behavior but also
// ensures correct behavior when using converters that consume all types.
converterFactories.add(new BuiltInConverters());
converterFactories.addAll(this.converterFactories);
return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
}
这里没有什么好解释的,只是对Retrofit的一些初始化工作。其中 //1 处获取了回调的线程,首先platform会调用 Platform.get() 来获取。get 会返回PLATFORM静态变量,静态变量调用findPlatform()来进行初始化。我们看一下具体实现。
private static Platform findPlatform() {
try {
Class.forName("android.os.Build");
if (Build.VERSION.SDK_INT != 0) {
return new Platform.Android();
}
} catch (ClassNotFoundException ignored) {
}
try {
Class.forName("java.util.Optional");
return new Platform.Java8();
} catch (ClassNotFoundException ignored) {
}
return new Platform();
}
方法首先会进行类加载,尝试寻找是否存在 android.os.Build 类,如果存在就会创建Platform.Android()对象。很显然这就是我们要找的对象。
static class Android extends Platform {
@Override public Executor defaultCallbackExecutor() {
return new Platform.Android.MainThreadExecutor();
}
//返回默认适配器工厂
@Override CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
if (callbackExecutor == null) throw new AssertionError();
return new ExecutorCallAdapterFactory(callbackExecutor);
}
static class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
@Override public void execute(Runnable r) {
handler.post(r);
}
}
}
defaultCallbackExecutor(),它将任务都交给handler来进行执行,因此我们的默认回调线程是主线程。前面的callbackExecutor 就是这里的MainThreadExecutor ()。
defaultCallAdapterFactory()创建了ExecutorCallAdapterFactory()工厂,从这里咱知道默认的适配器工厂为ExecutorCallAdapterFactory(就是返回值为Call的工厂)
扯得有点远,咱们回归正题。继续上示例代码
TestService service = retrofit.create(TestService.class);
service.getData()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<ResponseBody>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(ResponseBody user) {
try {
Log.i(TAG, "onNext: " + user.string());
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onError(Throwable e) {
Log.i(TAG, "onError: " + e.getMessage());
}
@Override
public void onComplete() {
}
});
这段代码我想大家不会陌生。创建完retrofit后,会调用retrofit::create(Service.class)来进行创建Service。我们来看看Service的创建过程。
public <T> T create(final Class<T> service) {
Utils.validateServiceInterface(service);
if (validateEagerly) {//这里就是之前设置的参数,是否懒加载(默认是懒加载)
eagerlyValidateMethods(service);//1
}
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
new InvocationHandler() {
private final Platform platform = Platform.get();
@Override public 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)) {//默认false,咱不管
return platform.invokeDefaultMethod(method, service, proxy, args);
}
//为当前method加载一个ServiceMethod出来
ServiceMethod<Object, Object> serviceMethod =
(ServiceMethod<Object, Object>) loadServiceMethod(method);//2
//创建Okhttpcall之后的网络请求会用到
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
//根据serviceMethod对okhttpcall进行适配
return serviceMethod.adapt(okHttpCall);//3
}
});
}
这里代码很简单,利用动态代理的形式对Service进行创建。不管如何网络请求都绕不开OkhttpCall对象。话不多说,先进性1处的分析。
private void eagerlyValidateMethods(Class<?> service) {
Platform platform = Platform.get();
//加载Service中所有的method
for (Method method : service.getDeclaredMethods()) {
if (!platform.isDefaultMethod(method)) {//platform.isDefaultMethod(method)默认为false
loadServiceMethod(method);
}
}
}
//存储method的信息,进入map中
private final Map<Method, ServiceMethod<?, ?>> serviceMethodCache = new ConcurrentHashMap<>();
ServiceMethod<?, ?> loadServiceMethod(Method method) {
ServiceMethod<?, ?> result = serviceMethodCache.get(method);
if (result != null) return result;
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
result = new ServiceMethod.Builder<>(this, method).build();//4
serviceMethodCache.put(method, result);
}
}
return result;
}
使用了双重检查锁,通过method在缓存中找,如果找不到则进行创建,并且加入缓存中。我们发现这里的loadServiceMethod()在 //2 处也有调用。因为此处是以缓存的方式进行存储,因此我们可以确定,之前的validateEagerly参数是懒加载的作用。
//4处代码暂且放一下,我们先进行 //3处的分析。
//serviceMethod.adapt(okHttpCall);
T adapt(Call<R> call) {
return callAdapter.adapt(call);
}
代码简单的让人摸不着头脑,在这里我们要知道这个T是我们方法的Call或者Observable的泛型。要想知道适配器的实现,我们必须要知道callAdapter为何物。
接下来我们看4处的代码 ServiceMethod 的创建
public ServiceMethod build() {
callAdapter = createCallAdapter();//创建CallAdapter
responseType = callAdapter.responseType();
if (responseType == Response.class || responseType == okhttp3.Response.class) {
throw methodError("'"
+ Utils.getRawType(responseType).getName()
+ "' is not a valid response body type. Did you mean ResponseBody?");
}
responseConverter = createResponseConverter();//创建转换器,这里不进行拓展
for (Annotation annotation : methodAnnotations) {
parseMethodAnnotation(annotation);//解析方法上的注解
}
...
return new ServiceMethod<>(this);
}
private CallAdapter<T, R> createCallAdapter() {
//获取method的返回值Type(需要注意,后面会用到)
Type returnType = method.getGenericReturnType();
...
//这里通过最终在这里进行创建
return (CallAdapter<T, R>) retrofit.callAdapter(returnType, annotations);
...
}
代码有点长,我截取重要的来进行分析。这里我们找到了callAdapter赋值的地方。retrofit::callAdapter()接着会调用retrofit::nextCallAdapter()方法,这里有一个skipPast参数,为null传递进来,需要注意一下。我们接着看一看nextCallAdapter()的实现
public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType,
Annotation[] annotations) {
checkNotNull(returnType, "returnType == null");
checkNotNull(annotations, "annotations == null");
//因为skipPast为null 所以这一步的执行结果应该为 start = -1+1 = 0
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;
}
}
...
}
callAdapterFactories看到这里可能大家就熟悉了,这不是我们调用的时候创建的工厂吗。我们创建的工厂实例会被丢入到这个集合里,那我们get的时候恰好就是拿到我们创建的工厂 。
这里我需要提一嘴的是当前的callAdapter是ServiceMethod的成员变量,而ServiceMethod和method进行绑定,所以一个method应该对应一个callAdapter才合理。因此这里 我们大胆猜测 callAdapter会根据method的returnType不同来返回不同的CallAdapterFactory。(如果创建的时候加入了RxJava2CallAdapterFactory,那么这里的callAdapterFactories就应该会两个值,一个是RxJava2CallAdapterFactory和ExecutorCallAdapterFactory)。
我们主要分析RxJava2CallAdapterFactory代码,ExecutorCallAdapterFactory较为简单,大家有兴趣的自行去看。下面会执行RxJava2CallAdapterFactory::get()方法
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
Class<?> rawType = getRawType(returnType);
...
boolean isFlowable = rawType == Flowable.class;
boolean isSingle = rawType == Single.class;
boolean isMaybe = rawType == Maybe.class;
//这里进行判断当前是否属于Rxjava适配器,不是返回null
if (rawType != Observable.class && !isFlowable && !isSingle && !isMaybe) {
return null;
}
boolean isResult = false;
boolean isBody = false;
Type responseType;
if (!(returnType instanceof ParameterizedType)) {
String name = isFlowable ? "Flowable"
: isSingle ? "Single"
: isMaybe ? "Maybe" : "Observable";
throw new IllegalStateException(name + " return type must be parameterized"
+ " as " + name + "<Foo> or " + name + "<? extends Foo>");
}
//获取returnType中的泛型Type
Type observableType = getParameterUpperBound(0, (ParameterizedType) returnType);
Class<?> rawObservableType = getRawType(observableType);
if (rawObservableType == Response.class) {
if (!(observableType instanceof ParameterizedType)) {
throw new IllegalStateException("Response must be parameterized"
+ " as Response<Foo> or Response<? extends Foo>");
}
responseType = getParameterUpperBound(0, (ParameterizedType) observableType);
} else if (rawObservableType == Result.class) {
if (!(observableType instanceof ParameterizedType)) {
throw new IllegalStateException("Result must be parameterized"
+ " as Result<Foo> or Result<? extends Foo>");
}
responseType = getParameterUpperBound(0, (ParameterizedType) observableType);
isResult = true;
} else {
//我们会执行到这里
responseType = observableType;
isBody = true; //这个关系到我们接下来创建的对象
}
//这里就是我们需要找到CallAdapter的实现类的
return new RxJava2CallAdapter(responseType, scheduler, isAsync, isResult, isBody, isFlowable,
isSingle, isMaybe, false);
}
我们先收一收思绪,前面我们讲的Retrofit::create()方法中动态代理返回的是callAdapter.adapter的对象。所以我们接下来看RxJava2CallAdapter的adapter方法,看它是如何进行适配的。
@Override public Object adapt(Call<R> call) {
//这里对Observable进行创建
Observable<Response<R>> responseObservable = isAsync
? new CallEnqueueObservable<>(call)
: new CallExecuteObservable<>(call);
Observable<?> observable;
if (isResult) {
observable = new ResultObservable<>(responseObservable);
} else if (isBody) {
//通过上面得知 isBody为true因此,会执行到这里,这个类主要是对响应结果进行包装,暂时先不管
observable = new BodyObservable<>(responseObservable);
} else {
observable = responseObservable;
}
...
return observable;
}
下面咱看一看CallExecuteObservable类的实现
final class CallExecuteObservable<T> extends Observable<Response<T>> {
private final Call<T> originalCall;
CallExecuteObservable(Call<T> originalCall) {
this.originalCall = originalCall;
}
//Observable执行subscribe时最终会调用这个方法(想了解更多的小伙伴可以看一下rxjava源码,了解一下架构方式)
@Override protected void subscribeActual(Observer<? super Response<T>> observer) {
// Since Call is a one-shot type, clone it for each new observer.
Call<T> call = originalCall.clone();//这个call就是前面传进来的okhttpCall
CallDisposable disposable = new CallDisposable(call);
observer.onSubscribe(disposable);
boolean terminated = false;
try {
//最后都会执行这一步进行网络请求
Response<T> response = call.execute();
if (!disposable.isDisposed()) {
observer.onNext(response);
}
if (!disposable.isDisposed()) {
terminated = true;
observer.onComplete();
}
} catch (Throwable t) {
Exceptions.throwIfFatal(t);
if (terminated) {
RxJavaPlugins.onError(t);
} else if (!disposable.isDisposed()) {
try {
observer.onError(t);
} catch (Throwable inner) {
Exceptions.throwIfFatal(inner);
RxJavaPlugins.onError(new CompositeException(t, inner));
}
}
}
}
}
到了这里我们进行一个总结,Retrofit::create方法中使用动态代理对每一个method进行拦截,并根据返回值的Type 来返回不同的adapter,我们使用Rxjava就是RxJava2CallAdapter这个适配器。在这个类中对Observable进行创建,并且在subscribe的时候调用OkhttpCall的execute()方法,来进行网络请求。并返回我们需要的结果Response。Rxjava会根据Response的结果来进行返回。到了这里我们应该对Retrofit的适配器模式有了大概的了解,现在唯一模糊的就是Response是怎么创建来的?
下面我们继续看OkhttpCall的execute()方法
@Override public Response<T> execute() throws IOException {
okhttp3.Call call;
synchronized (this) {
if (executed) throw new IllegalStateException("Already executed.");
executed = true;
if (creationFailure != null) {
if (creationFailure instanceof IOException) {
throw (IOException) creationFailure;
} else if (creationFailure instanceof RuntimeException) {
throw (RuntimeException) creationFailure;
} else {
throw (Error) creationFailure;
}
}
call = rawCall;
if (call == null) {
try {
call = rawCall = createRawCall();//这里会进行跟Okhttp联系起来,创建RawCall
} catch (IOException | RuntimeException | Error e) {
throwIfFatal(e); // Do not assign a fatal error to creationFailure.
creationFailure = e;
throw e;
}
}
}
if (canceled) {
call.cancel();
}
return parseResponse(call.execute());//call.execute()拿到rawCall,并执行execute()
}
继续看createRawCall()方法
private okhttp3.Call createRawCall() throws IOException {
okhttp3.Call call = serviceMethod.toCall(args);
if (call == null) {
throw new NullPointerException("Call.Factory returned null.");
}
return call;
}
向下跟 toCall()
okhttp3.Call toCall(@Nullable Object... args) throws IOException {
RequestBuilder requestBuilder = new RequestBuilder(httpMethod, baseUrl, relativeUrl, headers,
contentType, hasBody, isFormEncoded, isMultipart);
@SuppressWarnings("unchecked") // It is an error to invoke a method with the wrong arg types.
ParameterHandler<Object>[] handlers = (ParameterHandler<Object>[]) parameterHandlers;
int argumentCount = args != null ? args.length : 0;
if (argumentCount != handlers.length) {
throw new IllegalArgumentException("Argument count (" + argumentCount
+ ") doesn't match expected count (" + handlers.length + ")");
}
for (int p = 0; p < argumentCount; p++) {
handlers[p].apply(requestBuilder, args[p]);
}
return callFactory.newCall(requestBuilder.build());
}
最后会执行callFactory.newCall()方法。这个callFactory就是创建Retrofit时候的 client(),有映像的同学应该会发现,newCall会调用OkhttpClient的newCall()。这里就属于Okhttp的范畴了,我就不向下分析。我们继续回到上面call.execute()会返回一个response,这个response就是网络请求返回的结果。Okhttp采用的是Socket通信,网络请求后会进行阻塞等待返回结果,(我们可以将其看成是一个线程的同步执行)如果请求成功Response必然是存在值的。下面我们来看OkhttpCall的parseResponse方法。
Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
ResponseBody rawBody = rawResponse.body();
// Remove the body's source (the only stateful object) so we can pass the response along.
rawResponse = rawResponse.newBuilder()
.body(new NoContentResponseBody(rawBody.contentType(), rawBody.contentLength()))
.build();
int code = rawResponse.code();
if (code < 200 || code >= 300) {
try {
// Buffer the entire body to avoid future I/O.
ResponseBody bufferedBody = Utils.buffer(rawBody);
return Response.error(bufferedBody, rawResponse);
} finally {
rawBody.close();
}
}
if (code == 204 || code == 205) {
rawBody.close();
return Response.success(null, rawResponse);
}
ExceptionCatchingRequestBody catchingBody = new ExceptionCatchingRequestBody(rawBody);
try {
T body = serviceMethod.toResponse(catchingBody);//这里会根据我们设置Gson转换器,将body转换成javabean
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;
}
}
执行成功会调用 Response.success(body, rawResponse)
public static <T> Response<T> success(@Nullable T body, okhttp3.Response rawResponse) {
checkNotNull(rawResponse, "rawResponse == null");
if (!rawResponse.isSuccessful()) {
throw new IllegalArgumentException("rawResponse must be successful response");
}
return new Response<>(rawResponse, body, null);
}
然后根据body创建Response返回。
Retrofit的适配器就分析到这里。