我们网络访问已经有了OkHttp,那为什么还需要一个Retrofit呢?
我们先来看一下一个基本的OkHttp请求的步骤:
- String url = "http://wwww.baidu.com";
- OkHttpClient okHttpClient = new OkHttpClient();
- final Request request = new Request.Builder()
- .url(url)
- .get()//默认就是GET请求,可以不写
- .build();
- Call call = okHttpClient.newCall(request);
- call.enqueue(new Callback() {
- @Override
- public void onFailure(Call call, IOException e) {
- Log.d(TAG, "onFailure: ");
- }
-
- @Override
- public void onResponse(Call call, Response response) throws IOException {
- Log.d(TAG, "onResponse: " + response.body().string());
- }
- });
这样的请求其实有几个问题:
我们知道Retrofit是基于OkHttp的一层封装,Retrofit本身不负责网络请求,而是将请求交给OkHttp处理。我们知道,Retrofit的请求是写在一个个接口里面的,这样同样baseUrl的请求就可以写在一个接口里面,非常方便拓展和管理。而且直接将数据解析到javaBean,并且自动切换线程。这样就有效的解决了OkHttp的使用问题。

上图是对Retrofit职责的一个很好的描述。
我们来看一下Retrofit的基本使用:
- //step1
- Retrofit retrofit = new Retrofit.Builder()
- .baseUrl("https://www.wanandroid.com/")
- .addConverterFactory(GsonConverterFactory.create(new Gson()))
- .build();
- //step2
- ISharedListService sharedListService = retrofit.create(ISharedListService.class);
- //step3
- Call
sharedListCall = sharedListService.getSharedList(2,1); - //step4
- sharedListCall.enqueue(new Callback
() { - @Override
- public void onResponse(Call
call, Response response{ - if (response.isSuccessful()) {
- System.out.println(response.body().toString());
- }
- }
- @Override
- public void onFailure(Call
call, Throwable t) { - t.printStackTrace();
- }
- });
我们先来看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();//1
- }
-
- Executor callbackExecutor = this.callbackExecutor;
- if (callbackExecutor == null) {
- callbackExecutor = platform.defaultCallbackExecutor();//2
- }
-
- // Make a defensive copy of the adapters and add the default Call adapter.
- List
callAdapterFactories = new ArrayList<>(this.callAdapterFactories); - callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));
-
- // Make a defensive copy of the converters.
- List
converterFactories = - new ArrayList<>(
- 1 + this.converterFactories.size() + platform.defaultConverterFactoriesSize());
-
- // 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);
- converterFactories.addAll(platform.defaultConverterFactories());
-
- return new Retrofit(
- callFactory,
- baseUrl,
- unmodifiableList(converterFactories),
- unmodifiableList(callAdapterFactories),
- callbackExecutor,
- validateEagerly);
- }
- }
注释1处可见创建了一个OkHttpClient。这里也用到了建造者设计模式。那我们要思考一下,何时该使用建造者模式呢?好多人看了大量的设计模式书籍,可是代码风格依然一眼难尽!
- public static final class Builder {
- private final Platform platform;
- private @Nullable okhttp3.Call.Factory callFactory;
- private @Nullable HttpUrl baseUrl;
- private final List
converterFactories = new ArrayList<>(); - private final List
callAdapterFactories = new ArrayList<>(); - private @Nullable Executor callbackExecutor;
- private boolean validateEagerly;
-
- Builder(Platform platform) {
- this.platform = platform;
- }
-
- public Builder() {
- this(Platform.get());
- }
-
- Builder(Retrofit retrofit) {
- platform = Platform.get();
- callFactory = retrofit.callFactory;
- baseUrl = retrofit.baseUrl;
-
- // Do not add the default BuiltIntConverters and platform-aware converters added by build().
- for (int i = 1,
- size = retrofit.converterFactories.size() - platform.defaultConverterFactoriesSize();
- i < size;
- i++) {
- converterFactories.add(retrofit.converterFactories.get(i));
- }
-
- // Do not add the default, platform-aware call adapters added by build().
- for (int i = 0,
- size =
- retrofit.callAdapterFactories.size() - platform.defaultCallAdapterFactoriesSize();
- i < size;
- i++) {
- callAdapterFactories.add(retrofit.callAdapterFactories.get(i));
- }
-
- callbackExecutor = retrofit.callbackExecutor;
- validateEagerly = retrofit.validateEagerly;
- }
-
- /**
- * The HTTP client used for requests.
- *
- *
This is a convenience method for calling {@link #callFactory}.
- */
- public Builder client(OkHttpClient client) {
- return callFactory(Objects.requireNonNull(client, "client == null"));
- }
-
- /**
- * Specify a custom call factory for creating {@link Call} instances.
- *
- *
Note: Calling {@link #client} automatically sets this value.
- */
- public Builder callFactory(okhttp3.Call.Factory factory) {
- this.callFactory = Objects.requireNonNull(factory, "factory == null");
- return this;
- }
-
- /**
- * Set the API base URL.
- *
- * @see #baseUrl(HttpUrl)
- */
- public Builder baseUrl(URL baseUrl) {
- Objects.requireNonNull(baseUrl, "baseUrl == null");
- return baseUrl(HttpUrl.get(baseUrl.toString()));
- }
-
- /**
- * Set the API base URL.
- *
- * @see #baseUrl(HttpUrl)
- */
- public Builder baseUrl(String baseUrl) {
- Objects.requireNonNull(baseUrl, "baseUrl == null");
- return baseUrl(HttpUrl.get(baseUrl));
- }
-
- /**
- * Set the API base URL.
- *
- *
The specified endpoint values (such as with {@link GET @GET}) are resolved against this
- * value using {@link HttpUrl#resolve(String)}. The behavior of this matches that of an {@code
- *
- *
Base URLs should always end in {@code /}.
- *
- *
A trailing {@code /} ensures that endpoints values which are relative paths will correctly
- * append themselves to a base which has path components.
- *
- *
Correct:
- * Base URL: http://example.com/api/
- * Endpoint: foo/bar/
- * Result: http://example.com/api/foo/bar/
- *
- *
Incorrect:
- * Base URL: http://example.com/api
- * Endpoint: foo/bar/
- * Result: http://example.com/foo/bar/
- *
- *
This method enforces that {@code baseUrl} has a trailing {@code /}.
- *
- *
Endpoint values which contain a leading {@code /} are absolute.
- *
- *
Absolute values retain only the host from {@code baseUrl} and ignore any specified path
- * components.
- *
- *
Base URL: http://example.com/api/
- * Endpoint: /foo/bar/
- * Result: http://example.com/foo/bar/
- *
- *
Base URL: http://example.com/
- * Endpoint: /foo/bar/
- * Result: http://example.com/foo/bar/
- *
- *
Endpoint values may be a full URL.
- *
- *
Values which have a host replace the host of {@code baseUrl} and values also with a scheme
- * replace the scheme of {@code baseUrl}.
- *
- *
Base URL: http://example.com/
- * Endpoint: https://github.com/square/retrofit/
- * Result: https://github.com/square/retrofit/
- *
- *
Base URL: http://example.com
- * Endpoint: //github.com/square/retrofit/
- * Result: http://github.com/square/retrofit/ (note the scheme stays 'http')
- */
- public Builder baseUrl(HttpUrl baseUrl) {
- Objects.requireNonNull(baseUrl, "baseUrl == null");
- List
pathSegments = baseUrl.pathSegments(); - if (!"".equals(pathSegments.get(pathSegments.size() - 1))) {
- throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl);
- }
- this.baseUrl = baseUrl;
- return this;
- }
-
- /** Add converter factory for serialization and deserialization of objects. */
- public Builder addConverterFactory(Converter.Factory factory) {
- converterFactories.add(Objects.requireNonNull(factory, "factory == null"));
- return this;
- }
-
- /**
- * Add a call adapter factory for supporting service method return types other than {@link
- * Call}.
- */
- public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
- callAdapterFactories.add(Objects.requireNonNull(factory, "factory == null"));
- return this;
- }
-
- /**
- * The executor on which {@link Callback} methods are invoked when returning {@link Call} from
- * your service method.
- *
- *
Note: {@code executor} is not used for {@linkplain #addCallAdapterFactory custom method
- * return types}.
- */
- public Builder callbackExecutor(Executor executor) {
- this.callbackExecutor = Objects.requireNonNull(executor, "executor == null");
- return this;
- }
-
- /** Returns a modifiable list of call adapter factories. */
- public List
callAdapterFactories() { - return this.callAdapterFactories;
- }
-
- /** Returns a modifiable list of converter factories. */
- public List
converterFactories() { - return this.converterFactories;
- }
-
- /**
- * When calling {@link #create} on the resulting {@link Retrofit} instance, eagerly validate the
- * configuration of all methods in the supplied interface.
- */
- public Builder validateEagerly(boolean validateEagerly) {
- this.validateEagerly = validateEagerly;
- return this;
- }
-
- /**
- * Create the {@link Retrofit} instance using the configured values.
- *
- *
Note: If neither {@link #client} nor {@link #callFactory} is called a default {@link
- * OkHttpClient} will be created and used.
- */
- 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) {
- callbackExecutor = platform.defaultCallbackExecutor();
- }
-
- // Make a defensive copy of the adapters and add the default Call adapter.
- List
callAdapterFactories = new ArrayList<>(this.callAdapterFactories); - callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));
-
- // Make a defensive copy of the converters.
- List
converterFactories = - new ArrayList<>(
- 1 + this.converterFactories.size() + platform.defaultConverterFactoriesSize());
-
- // 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);
- converterFactories.addAll(platform.defaultConverterFactories());
-
- return new Retrofit(
- callFactory,
- baseUrl,
- unmodifiableList(converterFactories),
- unmodifiableList(callAdapterFactories),
- callbackExecutor,
- validateEagerly);
- }
- }
我们先来看一下Retrofit的静态内部类Builder,里面的baseUrl,addConverterFactory等方法返回的都是Builder类型,说明了在使用的时候可以做到可配置,另外一个大家都比较清楚,就是参数比较多的情况,一般认为在5个以上。
我们分析完Retrofit的使用的第一步,接下来看第二步:
ISharedListService sharedListService = retrofit.create(ISharedListService.class);
点进create看一下:
- public
T create(final Class 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 {
- // 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);
- }
- });
- }
大家可能或多或少了解过一些关于代理设计模式,可是你真的熟悉或者说了解代理设计模式吗?
代理模式分为静态代理和动态代理,如果大家不熟悉静态代理模式,可以看下我以前的一篇文章:
下面重点讲一下动态代理,我们先来看newProxyInstance这个方法:
- public static Object newProxyInstance(ClassLoader loader,
- Class>[] interfaces,
- InvocationHandler h)
- throws IllegalArgumentException
- {
发现返回的是一个Object类型的对象,所以create方法本质上是返回了一个实现指定接口的对象。
- public static Object newProxyInstance(ClassLoader loader,
- Class>[] interfaces,
- InvocationHandler h)
- throws IllegalArgumentException
- {
- Objects.requireNonNull(h);
-
- final Class>[] intfs = interfaces.clone();
-
- Class> cl = getProxyClass0(loader, intfs);
-
-
- try {
-
-
- final Constructor> cons = cl.getConstructor(constructorParams);
- final InvocationHandler ih = h;
- if (!Modifier.isPublic(cl.getModifiers())) {
-
-
- cons.setAccessible(true);
- // END Android-removed: Excluded AccessController.doPrivileged call.
- }
- return cons.newInstance(new Object[]{h});//1
- } catch (IllegalAccessException|InstantiationException e) {
- throw new InternalError(e.toString(), e);
- } catch (InvocationTargetException e) {
- Throwable t = e.getCause();
- if (t instanceof RuntimeException) {
- throw (RuntimeException) t;
- } else {
- throw new InternalError(t.toString(), t);
- }
- } catch (NoSuchMethodException e) {
- throw new InternalError(e.toString(), e);
- }
- }
注意注释1处,通过构造函数初始化了一个对象,并将h传了进去,这个h是啥呢?很明显:
是实现InvocationHandler接口的一个对象。我们来写一个create生成的实现传入接口的对象的伪代码帮大家理解一下动态代理:


我们前面看到cons.newInstance(new Object[]{h})传进来一个h,再看上图,调用了h的invoke方法,这样是不是有点顿悟的感觉。简而言之,动态代理的原理就是:Proxy.newProxyInstance生成一个实现某个接口的对象,并且传入一个实现InvocationHandler接口的对象,当该对象调用实现接口的方法时,实际上调用的实现InvocationHandler接口的对象的invoke方法,并且将接口方法和参数也传进来,后面在invoke里面反射调用。
这样讲大家可能还不是很明白,说的简单点吧:Retrofit请求我们写成一个一个的接口,而这些接口最终通过Proxy.newProxyInstance最终会生成实现这个接口的对象,这是第一步;而生成这个对象的时候,在构造中传入了实现InvocationHandler接口的的对象,紧接着调用这个对象的invoke方法,并将方法信息以及方法参数传过去,实际上实现这个接口的的方法调用是在实现InvocationHandler接口的的对象中进行的,而实现我们所写接口的对象的方法只是调用了this.h.invoke。
下面再讲一个Retrofit非常重要的一个点:线程切换。我们知道OkHttp的回调里面是没有切换线程的,这样我们使用的时候就会需要手动切换线程,不是那么的友好。
我们先看Retrofit里面的一段代码:
- public Retrofit build() {
-
-
- ···
- Executor callbackExecutor = this.callbackExecutor;
- if (callbackExecutor == null) {
- callbackExecutor = platform.defaultCallbackExecutor();//1
- }
-
- ···
- }
我们进注释1看看实现,我们是Android平台:
- static final class Android extends Platform {
- Android() {
- super(Build.VERSION.SDK_INT >= 24);
- }
-
- @Override
- public Executor defaultCallbackExecutor() {
- return new MainThreadExecutor();//1
- }
-
- @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 {
- private final Handler handler = new Handler(Looper.getMainLooper());
-
- @Override
- public void execute(Runnable r) {
- handler.post(r);//2
- }
- }
- }
原来本质上是用了Handler,记住一个很重要的结论:Android中线程切换最终都是Handler,进程间通信绝大部分都是Binder。
我们既然知道了Retrofit是使用Handler来进行线程切换的,那么它是如何使用的呢?
我们再来看下面的代码:
- 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)) {
- return platform.invokeDefaultMethod(method, service, proxy, args);
- }
- ServiceMethod
- (ServiceMethod
- OkHttpCall
- return serviceMethod.callAdapter.adapt(okHttpCall);//3
- }
- });
(注:这个代码是Retrofit2.3.0版本的,前面是2.9.0版本的,有些不一样,但是这个版本线程切换更好理解)
先来看注释1:
- 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();
- serviceMethodCache.put(method, result);
- }
- }
- return result;
- }
我们只需要关注一点,这里面传入了this,而这个this就是retrofit对象。
我们再来关注OKHttpCall:
- final class OkHttpCall
implements Call { - private final ServiceMethod
serviceMethod; - private final @Nullable Object[] args;
-
- private volatile boolean canceled;
-
- @GuardedBy("this")
- private @Nullable okhttp3.Call rawCall;
- @GuardedBy("this")
- private @Nullable Throwable creationFailure; // Either a RuntimeException or IOException.
- @GuardedBy("this")
- private boolean executed;
-
- OkHttpCall(ServiceMethod
serviceMethod, @Nullable Object[] args) { - this.serviceMethod = serviceMethod;
- this.args = args;
- }
-
- ···
-
- @Override public void enqueue(final Callback
callback) { - checkNotNull(callback, "callback == null");
-
- okhttp3.Call call;
- Throwable failure;
-
- synchronized (this) {
- if (executed) throw new IllegalStateException("Already executed.");
- executed = true;
-
- call = rawCall;
- failure = creationFailure;
- if (call == null && failure == null) {
- try {
- call = rawCall = createRawCall();
- } catch (Throwable t) {
- failure = creationFailure = t;
- }
- }
- }
-
- if (failure != null) {
- callback.onFailure(this, failure);
- return;
- }
-
- if (canceled) {
- call.cancel();
- }
-
- call.enqueue(new okhttp3.Callback() {
- @Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse)
- throws IOException {
- Response
response; - try {
- response = parseResponse(rawResponse);
- } catch (Throwable e) {
- callFailure(e);
- return;
- }
- callSuccess(response);
- }
-
- @Override public void onFailure(okhttp3.Call call, IOException e) {
- try {
- callback.onFailure(OkHttpCall.this, e);
- } catch (Throwable t) {
- t.printStackTrace();
- }
- }
-
- private void callFailure(Throwable e) {
- try {
- callback.onFailure(OkHttpCall.this, e);
- } catch (Throwable t) {
- t.printStackTrace();
- }
- }
-
- private void callSuccess(Response
response) { - try {
- callback.onResponse(OkHttpCall.this, response);
- } catch (Throwable t) {
- t.printStackTrace();
- }
- }
- });
- }
-
- @Override public synchronized boolean isExecuted() {
- return executed;
- }
-
-
-
- private okhttp3.Call createRawCall() throws IOException {
- Request request = serviceMethod.toRequest(args);
- okhttp3.Call call = serviceMethod.callFactory.newCall(request);
- if (call == null) {
- throw new NullPointerException("Call.Factory returned null.");
- }
- return call;
- }
-
- Response
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);
- 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;
- }
- }
- ···
- }
我们发现,内部创建了一个OkHttp的call,执行的也是OkHttp创建的call的异步方法,这里也可以看出来Retrofit的网络请求其实是交给OkHttp来处理的。我们再来关注一下这段代码:
- private void callSuccess(Response
response) { - try {
- callback.onResponse(OkHttpCall.this, response);
- } catch (Throwable t) {
- t.printStackTrace();
- }
- }
这个时候线程还没有切换,那么这个callback又是什么呢?我们看下面一段代码:
- final class ExecutorCallAdapterFactory extends CallAdapter.Factory {
- final Executor callbackExecutor;
-
- ExecutorCallAdapterFactory(Executor callbackExecutor) {
- this.callbackExecutor = callbackExecutor;
- }
-
- @Override
- public CallAdapter, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
- if (getRawType(returnType) != Call.class) {
- return null;
- }
- final Type responseType = Utils.getCallResponseType(returnType);
- return new CallAdapter
- @Override public Type responseType() {
- return responseType;
- }
-
- @Override public Call
- return new ExecutorCallbackCall<>(callbackExecutor, call);
- }
- };
- }
-
- static final class ExecutorCallbackCall
implements Call { - final Executor callbackExecutor;
- final Call
delegate; -
- ExecutorCallbackCall(Executor callbackExecutor, Call
delegate) { - this.callbackExecutor = callbackExecutor;
- this.delegate = delegate;
- }
-
- @Override public void enqueue(final Callback
callback) { - checkNotNull(callback, "callback == null");
-
- delegate.enqueue(new Callback
() {//注释1 - @Override public void onResponse(Call
call, final Response response) { - callbackExecutor.execute(new Runnable() {
- @Override public void run() {
- 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);
- }
- }
- });
- }
-
- @Override public void onFailure(Call
call, final Throwable t) { - callbackExecutor.execute(new Runnable() {
- @Override public void run() {
- callback.onFailure(ExecutorCallbackCall.this, t);
- }
- });
- }
- });
- }
-
- @Override public boolean isExecuted() {
- return delegate.isExecuted();
- }
-
- @Override public Response
execute() throws IOException { - return delegate.execute();
- }
-
- @Override public void cancel() {
- delegate.cancel();
- }
-
- @Override public boolean isCanceled() {
- return delegate.isCanceled();
- }
-
- @SuppressWarnings("CloneDoesntCallSuperClone") // Performing deep clone.
- @Override public Call
clone() { - return new ExecutorCallbackCall<>(callbackExecutor, delegate.clone());
- }
-
- @Override public Request request() {
- return delegate.request();
- }
- }
- }
这个delegate就是OkHttpCall,我们传了一个实现CallBack接口的对象进去。接着来看onResponse方法,关注callbackExecutor,这又是个什么东西呢?不着急我们一点一点分析。
我们回过头来再看这一行代码:
serviceMethod.callAdapter.adapt(okHttpCall)
顺着这一行代码往下推:这个callAdapter是个啥?
- public ServiceMethod build() {
- callAdapter = createCallAdapter();
- ```
- }
- private CallAdapter
createCallAdapter() { - Type returnType = method.getGenericReturnType();
- if (Utils.hasUnresolvableType(returnType)) {
- throw methodError(
- "Method return type must not include a type variable or wildcard: %s", returnType);
- }
- if (returnType == void.class) {
- throw methodError("Service methods cannot return void.");
- }
- Annotation[] annotations = method.getAnnotations();
- try {
- //noinspection unchecked
- return (CallAdapter
) retrofit.callAdapter(returnType, annotations); - } catch (RuntimeException e) { // Wide exception range because factories are user code.
- throw methodError(e, "Unable to create call adapter for %s", returnType);
- }
- }
调用了retrofit的callAdapter方法:
- public CallAdapter, ?> callAdapter(Type returnType, Annotation[] annotations) {
- return nextCallAdapter(null, returnType, annotations);
- }
-
- /**
- * Returns the {@link CallAdapter} for {@code returnType} from the available {@linkplain
- * #callAdapterFactories() factories} except {@code skipPast}.
- *
- * @throws IllegalArgumentException if no call adapter available for {@code type}.
- */
- public CallAdapter, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType,
- Annotation[] annotations) {
- checkNotNull(returnType, "returnType == null");
- checkNotNull(annotations, "annotations == null");
-
- int start = adapterFactories.indexOf(skipPast) + 1;
- for (int i = start, count = adapterFactories.size(); i < count; i++) {
- CallAdapter, ?> adapter = adapterFactories.get(i).get(returnType, annotations, this);//注释处
- if (adapter != null) {
- return adapter;
- }
- }
-
- StringBuilder builder = new StringBuilder("Could not locate call adapter for ")
- .append(returnType)
- .append(".\n");
- if (skipPast != null) {
- builder.append(" Skipped:");
- for (int i = 0; i < start; i++) {
- builder.append("\n * ").append(adapterFactories.get(i).getClass().getName());
- }
- builder.append('\n');
- }
- builder.append(" Tried:");
- for (int i = start, count = adapterFactories.size(); i < count; i++) {
- builder.append("\n * ").append(adapterFactories.get(i).getClass().getName());
- }
- throw new IllegalArgumentException(builder.toString());
- }
注意一下注释处:我们从adapterFactories里面去拿,那么callAdapter什么时候加入这个集合的呢?
- Executor callbackExecutor = this.callbackExecutor;
- if (callbackExecutor == null) {
- callbackExecutor = platform.defaultCallbackExecutor();
- }
-
- // Make a defensive copy of the adapters and add the default Call adapter.
- List
adapterFactories = new ArrayList<>(this.adapterFactories); - adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
-
- static class Android extends Platform {
- @Override public Executor defaultCallbackExecutor() {
- return new 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);
- }
- }
- }
终于找到了ExecutorCallAdapterFactory!这样跟前面结合起来就形成了一个完美的闭环不是吗?
我们最后再来理一理这个逻辑,可能还是有很多同学不是很明白:
Retrofit的Call调用enqueue方法,其实是ExecutorCallAdapterFactory的内部类ExecutorCallbackCall的enqueue方法,而这个方法其实调用了OkHttpCall的enqueue方法,而OkHttpCall的enqueue方法执行的是OKHttp的Call得enqueue方法。线程切换就是在callbackExecutor.execute这里完成的,这个callbackExecutor其实是一个MainThreadExecutor(),内部封装了一个Handler,实现了线程切换。