Retrofit2源码分析

一、概述

    在了解Retrofit2源码架构之前先说明,本文默认读者对Retrofit2框架的使用有一定了解,除此之外还要先熟悉okhttp3框架和Java代理模式中的动态代理,不然后面咱们看Retrofit2源码时会很难理解:

    Java代理模式

    严格地说,Retrofit2并不是一个网络请求交易框架,它只是对网络请求框架的封装。底层把实现交给了okhttp3,由okhttp3做真正的网络请求。Retrofit2框架和其他的用于网络请求的框架流程大体相同,Retrofit2优势在于,它使用了大量的设计模式将功能模块解耦,这样做的好处在于可以让流程更加清晰,可塑性更强。

    注:本文基于Retrofit 2.4.0版本的源码分析。

 

二、Retrofit2源码地址

    Retrofit2源码地址:https://github.com/square/retrofit

 

三、Retrofit2简单使用

    1、首先创建用于网络请求的API接口:


 
 
  1. public interface NetService {
  2. @GET( "cozing")
  3. Call<NetResponse> serviceApi();
  4. }

    2、创建用于接收请求返回的数据接收:


 
 
  1. public class NetResponse {
  2. private int id;
  3. private String name;
  4. }

    3、创建Retrofit实例并做交易请求:


 
 
  1. public class Retrofit2TestForBlogActivity extends BaseActivity{
  2. ...
  3. private void retrofitTest(){
  4. Retrofit retrofit = new Retrofit.Builder()
  5. .baseUrl( "https://github.com/") //必须以"/"结尾,不然将抛出异常
  6. .addConverterFactory(GsonConverterFactory.create())
  7. //.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
  8. .build();
  9. NetService netApi = retrofit.create(NetService.class);
  10. Call<NetResponse> call = netApi.serviceApi();
  11. try {
  12. //① 同步请求
  13. Response response = call.execute();
  14. } catch (IOException e) {
  15. e.printStackTrace();
  16. }
  17. //②异步请求
  18. call.enqueue( new Callback<NetResponse>() {
  19. @Override
  20. public void onResponse(Call<NetResponse> call, Response<NetResponse> response) {
  21. }
  22. @Override
  23. public void onFailure(Call<NetResponse> call, Throwable t) {
  24. }
  25. });
  26. }
  27. }

      通过以上代码,咱们完成了请求,其中咱们向:

url = https://github.com/cozing
 
 

发送GET请求,在注释①处发起同步请求,在注释②处发送异步请求,交易的结果通过调用返回的Response对象实例的response.body()获取,这个结果就是咱们在构建网络请求时传入的NetResponse数据结构。

接下来看Retrofit2整体架构流程图。

 

四、架构流程

1、流程图

 

2、流程讲解

    1、创建Retrofit实例;

    2、创建网络请求接口和相关属性注解;

    3、通过动态代理解析请求接口的注解,并生成网络请求对象;

    4、通过CallAdapter进行平台适配,平台包括(Android/java8/iOS);

    5、通过OkHttpCall发送网络请求;

    6、通过Converter数据转换适配器转换交易返回的数据;

    7、通过线程切换执行器切换到主线程(仅限异步请求)。

 

五、源码分析

1、Retrofit的内部成员变量


 
 
  1. public final class Retrofit {
  2. private final Map<Method, ServiceMethod <?, ?>> serviceMethodCache = new ConcurrentHashMap<>(); //网络请求缓存,如:请求方法、请求头、请求体,各种适配器等
  3. final okhttp3.Call.Factory callFactory; //okhttp工厂,真正发送交易的处理类
  4. final HttpUrl baseUrl; //请求url前半部,基地址
  5. final List<Converter.Factory> converterFactories; //数据转换器工厂集
  6. final List<CallAdapter.Factory> adapterFactories; //网络请求适配器工厂集
  7. final @Nullable Executor callbackExecutor; //异步请求结果线程切换执行器
  8. final boolean validateEagerly; //标志位、是否马上解析接口方法
  9. ...
  10. }

2、Retrofit内部类Builder


 
 
  1. public final class Retrofit {
  2. ...
  3. public static final class Builder {
  4. private final Platform platform; //适配平台,通常默认android
  5. private @Nullable okhttp3.Call.Factory callFactory; //okhttp网络请求工厂,默认okhttp
  6. private HttpUrl baseUrl; //基地址
  7. private final List<Converter.Factory> converterFactories = new ArrayList<>(); //数据转换器集,用于生产数据转换器,默认GsonConverterFactory
  8. private final List<CallAdapter.Factory> adapterFactories = new ArrayList<>(); //网络请求适配器,如RxJava2CallAdapterFactory
  9. private @Nullable Executor callbackExecutor; //执行异步回调的线程切换
  10. private boolean validateEagerly; //是否立即解析接口注解方法
  11. }
  12. ...
  13. }

3、创建Retrofit实例


 
 
  1. Retrofit retrofit = new Retrofit.Builder()
  2. .baseUrl( "https://github.com")
  3. .addConverterFactory(GsonConverterFactory.create())
  4. .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
  5. .build();

内部类Builder实现:


 
 
  1. public final class Retrofit {
  2. ...
  3. public static final class Builder {
  4. ...
  5. Builder(Platform platform) {
  6. this.platform = platform;
  7. converterFactories.add( new BuiltInConverters()); //添加默认数据解析器
  8. }
  9. public Builder() {
  10. this(Platform.get());
  11. }
  12. }
  13. }

    咱们在创建Builder实例时调用的是Builder的无参构造放法,里面调用了Builder(Platform)这个构造方法,传入的是Platform.get()返回数据,这个方法是获取适配平台,默认是Android,其他平台咱们不做过多分析,直接查看Android:


 
 
  1. class Platform {
  2. ...
  3. static class Android extends Platform {
  4. @Override public Executor defaultCallbackExecutor() {
  5. return new MainThreadExecutor();
  6. }
  7. @Override CallAdapter. Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
  8. if (callbackExecutor == null) throw new AssertionError();
  9. return new ExecutorCallAdapterFactory(callbackExecutor);
  10. }
  11. static class MainThreadExecutor implements Executor {
  12. //默认线程切换是切换到主线程
  13. private final Handler handler = new Handler(Looper.getMainLooper());
  14. @Override public void execute(Runnable r) {
  15. handler.post(r);
  16. }
  17. }
  18. }
  19. ...
  20. }

    可以看到在创建Builder实例的设配平台时,将工作线程切换到了主线程,这也是后面可以通过主线程回调返回请求数据的原因。

    接着将会在Builder的有参构造方法中的添加Retrofit默认的数据解析器:

converterFactories.add(new BuiltInConverters());
 
 

4、Builder.build()方法


 
 
  1. public final class Retrofit {
  2. ...
  3. public static final class Builder {
  4. ...
  5. public Retrofit build() {
  6. if (baseUrl == null) { //对baseurl进行非空判断
  7. throw new IllegalStateException( "Base URL required.");
  8. }
  9. //注释①
  10. okhttp3.Call.Factory callFactory = this.callFactory;
  11. if (callFactory == null) {
  12. callFactory = new OkHttpClient(); //创建okhttp客户端
  13. }
  14. //注释②
  15. Executor callbackExecutor = this.callbackExecutor;
  16. if (callbackExecutor == null) {
  17. callbackExecutor = platform.defaultCallbackExecutor();
  18. }
  19. List<CallAdapter.Factory> adapterFactories = new ArrayList<>( this.adapterFactories);
  20. adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
  21. List<Converter.Factory> converterFactories = new ArrayList<>( this.converterFactories);
  22. return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,
  23. callbackExecutor, validateEagerly);
  24. }
  25. }
  26. }

    首先咱们看注释①处,上面说过Retrofit2框架的底层发送交易其实是提交给了okhttp框架,在okhttp3源码讲解时咱们说过在okhttp中OkhttpClient在整个进程中只创建一次,所以在这里做了相关判断。

    注释②处,可以看到是获取回调执行器,如果没有设置回调执行器,就创建一个默认的主线程回调执行器。

    最后调用Retrofit的构造方法,创建一个Retrofit实例。可以看到整个创建Retrofit过程中,通过构建者模式来执行一系列初始化和对象的创建。

5、retrofit.create()

    接着咱们创建了网络请求接口类NetService.class,在下面的步骤中咱们调用retrofit.create(NetService.class),这个方法是Retrofit的核心,内部采用动态代理,将咱们自定义的网络请求接口转换成一个ServiceMethod对象,ServiceMethod就是咱们Retrofit中的具体请求对象,里面封装了网络请求所必须的全部信息,包括请求方法、url、请求头、请求体等网络配置参数!

    咱们现在看看create()源码:


 
 
  1. ...
  2. public <T> T create( final Class<T> service) {
  3. Utils.validateServiceInterface(service);
  4. if (validateEagerly) { //创建retrofit实例时提到的标志位
  5. //注释①
  6. eagerlyValidateMethods(service);
  7. }
  8. //注释②
  9. return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
  10. new InvocationHandler() {
  11. private final Platform platform = Platform. get();
  12. //注释③
  13. @Override public Object invoke(Object proxy, Method method, @Nullable Object[] args)
  14. throws Throwable {
  15. if (method.getDeclaringClass() == Object. class) {
  16. return method.invoke( this, args);
  17. }
  18. if (platform.isDefaultMethod(method)) {
  19. return platform.invokeDefaultMethod(method, service, proxy, args);
  20. }
  21. ServiceMethod<Object, Object> serviceMethod =
  22. (ServiceMethod<Object, Object>) loadServiceMethod(method);
  23. OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
  24. return serviceMethod.callAdapter.adapt(okHttpCall);
  25. }
  26. });
  27. }
  28. ...

    咱们先看注释①处,如果提前验证的标志位为true,将会调用eagerlyValidateMethods(service)方法,咱们来看:


 
 
  1. ...
  2. private void eagerlyValidateMethods(Class<?> service) {
  3. Platform platform = Platform. get();
  4. for (Method method : service.getDeclaredMethods()) {
  5. if (!platform.isDefaultMethod(method)) {
  6. loadServiceMethod(method);
  7. }
  8. }
  9. }
  10. ...

    可以看到这个方法内部通过反射机制,来获取咱们自定义的请求接口对象类的内部方法。isDefaultMethod默认为false,因此loadServiceMethod(method)方法一定会走到,咱们接着看这个方法:


 
 
  1. ...
  2. ServiceMethod<?, ?> loadServiceMethod(Method method) {
  3. ServiceMethod<?, ?> result = serviceMethodCache. get(method);
  4. if (result != null) return result;
  5. synchronized (serviceMethodCache) {
  6. result = serviceMethodCache. get(method);
  7. if (result == null) {
  8. result = new ServiceMethod.Builder<>( this, method).build();
  9. serviceMethodCache.put(method, result);
  10. }
  11. }
  12. return result;
  13. }
  14. ...

    其中serviceMethodCache是一个ConcurrentHashMap实例,ConcurrentHashMap是HashMap的一个线程安全的、支持高效并发的版本。继续看代码,创建serviceMethod时并不是每次都创建一个新的实例,而是先去缓存吃中去获取,如果缓存池中没有存储,则会调用builder构建者模式去重新创建method,并将该对象实例存入serviceMethodCache缓存池中。

    接着看注释②,返回了一个动态代理对象,如果不清楚什么是动态代理,请点击这里。熟悉动态代理模式的童鞋应该都知道

真正处理事务逻辑的地方是在代理对象的invoke回调方法内,在Retrofit2代码里,也就是注释③处。

    看注释③的invoke方法,对Retrofit源码理解的重中之重,就是这个方法中的最后三行。接下来咱们将在6、7、8点详细分析这三行代码。

6、loadServiceMethod()

    这个方法用于加载serviceMethod,一个serviceMethod对应咱们定义的网络请求接口中的一个方法,比如栗子中的serviceApi()这个方法。接着来看loadServiceMethod源码:


 
 
  1. ...
  2. ServiceMethod<?, ?> loadServiceMethod(Method method) {
  3. ServiceMethod<?, ?> result = serviceMethodCache. get(method);
  4. if (result != null) return result;
  5. synchronized (serviceMethodCache) {
  6. result = serviceMethodCache. get(method);
  7. if (result == null) {
  8. result = new ServiceMethod.Builder<>( this, method).build();
  9. serviceMethodCache.put(method, result);
  10. }
  11. }
  12. return result;
  13. }
  14. ...

    先看ServiceMethod的成员变量:


 
 
  1. final class ServiceMethod<R, T> {
  2. ...
  3. private final okhttp3.Call.Factory callFactory; //okhttp call的工厂
  4. private final CallAdapter<R, T> callAdapter; //网络请求适配器
  5. private final HttpUrl baseUrl; //基地址
  6. private final Converter<ResponseBody, R> responseConverter; //数据转换器
  7. private final String httpMethod; //网络请求方法
  8. private final String relativeUrl; //网络请求相对地址,和基地址拼接成完整地址
  9. private final Headers headers; //请求头
  10. private final MediaType contentType; //请求体
  11. private final boolean hasBody;
  12. private final boolean isFormEncoded;
  13. private final boolean isMultipart;
  14. private final ParameterHandler<?>[] parameterHandlers; //方法参数处理器
  15. ...
  16. }

    咱们开始时候说过,Retrofit2底层是基于okhttp框架来发送请求,可以看到在ServiceMrthod中维护了okhttp用于网络请求的Call工厂,用于生产Call,并且ServiceMrthod声明了网络请求所需元素的所有基本信息。咱们看ServiceMrthod的源码发现,它和Retrofit这个类的初始化非常相似,都是通过构建者模式来创建实例。咱们回过头看loadServiceMethod()方法的:


 
 
  1. ...
  2. result = new ServiceMethod.Builder<>( this, method).build();
  3. ...

这一行,跟进去Builder内部类:


 
 
  1. final class ServiceMethod<R, T> {
  2. ...
  3. Builder(Retrofit retrofit, Method method) {
  4. this.retrofit = retrofit; //retrofit实例
  5. this.method = method; //网络请求方法
  6. this.methodAnnotations = method.getAnnotations(); //网络请求方法的注解
  7. this.parameterTypes = method.getGenericParameterTypes(); //获取网络请求方法里的注解的类型
  8. this.parameterAnnotationsArray = method.getParameterAnnotations(); //获取网络请求方法里的注解的内容
  9. }
  10. ...
  11. }

    然后调用ServiceMrthod


 
 
  1. ...
  2. static final class Builder<T, R> {
  3. ...
  4. public ServiceMethod build() {
  5. //注释①
  6. callAdapter = createCallAdapter();
  7. responseType = callAdapter.responseType();
  8. if (responseType == Response.class || responseType == okhttp3.Response.class) {
  9. throw methodError( "'"
  10. + Utils.getRawType(responseType).getName()
  11. + "' is not a valid response body type. Did you mean ResponseBody?");
  12. }
  13. //注释②
  14. responseConverter = createResponseConverter();
  15. //注释③
  16. for (Annotation annotation : methodAnnotations) {
  17. parseMethodAnnotation(annotation);
  18. }
  19. ...
  20. //注释④
  21. int parameterCount = parameterAnnotationsArray.length;
  22. parameterHandlers = new ParameterHandler<?>[parameterCount];
  23. for ( int p = 0; p < parameterCount; p++) {
  24. Type parameterType = parameterTypes[p];
  25. if (Utils.hasUnresolvableType(parameterType)) {
  26. throw parameterError(p, "Parameter type must not include a type variable or wildcard: %s",
  27. parameterType);
  28. }
  29. Annotation[] parameterAnnotations = parameterAnnotationsArray[p];
  30. if (parameterAnnotations == null) {
  31. throw parameterError(p, "No Retrofit annotation found.");
  32. }
  33. parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);
  34. }
  35. ...
  36. return new ServiceMethod<>( this);
  37. }
  38. ...
  39. ...

    看注释①的createCallAdapter,创建callAdapter,内部实现:


 
 
  1. ...
  2. private CallAdapter<T, R> createCallAdapter() {
  3. Type returnType = method.getGenericReturnType();
  4. if (Utils.hasUnresolvableType(returnType)) {
  5. throw methodError(
  6. "Method return type must not include a type variable or wildcard: %s", returnType);
  7. }
  8. if (returnType == void.class) {
  9. throw methodError( "Service methods cannot return void.");
  10. }
  11. Annotation[] annotations = method.getAnnotations();
  12. try {
  13. return (CallAdapter<T, R>) retrofit.callAdapter(returnType, annotations);
  14. } catch (RuntimeException e) { // Wide exception range because factories are user code.
  15. throw methodError(e, "Unable to create call adapter for %s", returnType);
  16. }
  17. }
  18. ...

    这个方法主要是根据网络请求接口中的方法和方法内注解的类型,从retrofit中获取网络请求接口适配器。首先从网络请求接口方法中获取注释,然后根据注释和注释返回类型,接着调用retrofit.callAdapter()方法从retrofit中获取适配器。咱们跟着代码会发发现其实最后调用的是retrofit的nextCallAdapter(),来看看它内部实现的主要代码:


 
 
  1. ...
  2. public CallAdapter<?, ?> nextCallAdapter( @Nullable CallAdapter.Factory skipPast, Type returnType,
  3. Annotation[] annotations) {
  4. ...
  5. int start = callAdapterFactories.indexOf(skipPast) + 1;
  6. for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
  7. CallAdapter<?, ?> adapter = callAdapterFactories. get(i). get(returnType, annotations, this);
  8. if (adapter != null) {
  9. return adapter;
  10. }
  11. }
  12. ...
  13. }
  14. ...

    在for循环中,根据请求参数在网络适配工厂中创建网络适配器并返回该适配器,

    接着看build()方法中的注释②:

responseConverter = createResponseConverter();
 
 

    跟进去:


 
 
  1. ...
  2. private Converter<ResponseBody, T> createResponseConverter() {
  3. Annotation[] annotations = method.getAnnotations();
  4. try {
  5. return retrofit.responseBodyConverter(responseType, annotations);
  6. } catch (RuntimeException e) { // Wide exception range because factories are user code.
  7. throw methodError(e, "Unable to create converter for %s", responseType);
  8. }
  9. }
  10. ...

    这个方法是创建网络请求返回数据转换器,和创建网络请求适配器的方式一样,调用的是retrofit的responseBodyConverter()方法,内部真正调用的是nextResponseBodyConverter()方法,nextResponseBodyConverter()的内部主要实现:


 
 
  1. ...
  2. public <T> Converter<ResponseBody, T> nextResponseBodyConverter(
  3. ...
  4. int start = converterFactories.indexOf(skipPast) + 1;
  5. for ( int i = start, count = converterFactories.size(); i < count; i++) {
  6. Converter<ResponseBody, ?> converter =
  7. converterFactories. get(i).responseBodyConverter(type, annotations, this);
  8. if (converter != null) {
  9. return (Converter<ResponseBody, T>) converter;
  10. }
  11. }
  12. ...
  13. }
  14. ...

    可以看到,和创建网络请求适配器一样的创建方法,根据响应类型和请求方法注释数值,从数据转换器工厂中创建数据转换器并返回。

    继续看build()方法中的注释③:


 
 
  1. for (Annotation annotation : methodAnnotations) {
  2. parseMethodAnnotation( annotation);
  3. }

是解析请求接口中的所有注释。

    接着看注释④的代码:


 
 
  1. ...
  2. public ServiceMethod build() {
  3. ...
  4. int parameterCount = parameterAnnotationsArray.length;
  5. parameterHandlers = new ParameterHandler<?>[parameterCount];
  6. for ( int p = 0; p < parameterCount; p++) {
  7. Type parameterType = parameterTypes[p];
  8. if (Utils.hasUnresolvableType(parameterType)) {
  9. throw parameterError(p, "Parameter type must not include a type variable or wildcard: %s",
  10. parameterType);
  11. }
  12. Annotation[] parameterAnnotations = parameterAnnotationsArray[p];
  13. if (parameterAnnotations == null) {
  14. throw parameterError(p, "No Retrofit annotation found.");
  15. }
  16. parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);
  17. }
  18. ...
  19. }
  20. ....

    这部分做的主要是解析网络请求接口的参数,包括自定义请求接口参数和配置的请求参数,其中ParameterHandler类就是接口参数解析器。

    至此,loadServiceMethod()方法的分析完成,这个方法主要是创建并加载ServiceMehod,用于解析网络请求接口参数、网络请求适配器、response数据解析器等工作。

7、创建OkHttpCall对象

OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
 
 

    咱们前面说过Retrofit2框架的交易发送是由okhttp实现, 所以很容易想到,这个OkHttpCall就是对okhttp的call对象的封装,咱们现在看OkHttpCall的实现:


 
 
  1. final class OkHttpCall<T> implements Call<T> {
  2. ...
  3. @GuardedBy( "this")
  4. private @Nullable okhttp3.Call rawCall;
  5. ...
  6. @Override public void enqueue(final Callback<T> callback) {
  7. call.enqueue( new okhttp3.Callback() {
  8. @Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
  9. Response<T> response;
  10. try {
  11. response = parseResponse(rawResponse);
  12. } catch (Throwable e) {
  13. callFailure(e);
  14. return;
  15. }
  16. try {
  17. callback.onResponse(OkHttpCall. this, response);
  18. } catch (Throwable t) {
  19. t.printStackTrace();
  20. }
  21. }
  22. @Override public void onFailure(okhttp3.Call call, IOException e) {
  23. callFailure(e);
  24. }
  25. private void callFailure(Throwable e) {
  26. try {
  27. callback.onFailure(OkHttpCall. this, e);
  28. } catch (Throwable t) {
  29. t.printStackTrace();
  30. }
  31. }
  32. });
  33. ...
  34. @Override public Response<T> execute() throws IOException {
  35. okhttp3.Call call;
  36. synchronized ( this) {
  37. if (executed) throw new IllegalStateException( "Already executed.");
  38. executed = true;
  39. if (creationFailure != null) {
  40. if (creationFailure instanceof IOException) {
  41. throw (IOException) creationFailure;
  42. } else if (creationFailure instanceof RuntimeException) {
  43. throw (RuntimeException) creationFailure;
  44. } else {
  45. throw (Error) creationFailure;
  46. }
  47. }
  48. call = rawCall;
  49. if (call == null) {
  50. try {
  51. call = rawCall = createRawCall();
  52. } catch (IOException | RuntimeException | Error e) {
  53. throwIfFatal(e); // Do not assign a fatal error to creationFailure.
  54. creationFailure = e;
  55. throw e;
  56. }
  57. }
  58. }
  59. if (canceled) {
  60. call.cancel();
  61. }
  62. return parseResponse(call.execute());
  63. }
  64. ...
  65. }

    代码有点多,但是逻辑还是很清晰的,内部维护了一个okhttp3.Call rawCall的对象,接着看下面两个方法:enqueue()和execute(),可以看到内部调用的是rawCall的对应方法,也就是调用okhttp3.Call的enqueue()和execute()。

8、serviceMethod.adapt(okHttpCall)

    这个方法很显然使用适配器模式,将某些咱们需要处理的事件,适配成其他平台可以使用的类型,并在该平台使用。这里调用serviceMethod的adapt适配方法,传入了上面步骤7中创建的OkHttpCall实例,并将适配对象返回。adapt()方法源码:


 
 
  1. final class ServiceMethod<R, T> {
  2. ...
  3. T adapt(Call<R> call) {
  4. return callAdapter.adapt(call);
  5. }
  6. ...
  7. }

    可以看到内部调用的是callAdapter.adapter(call),而callAdapter对象实例是在loadServiceMethod()方法中调用ServiceMethod构建者模式创建实例时候创建的:


 
 
  1. final class ServiceMethod<R, T> {
  2. ...
  3. static final class Builder<T, R> {
  4. ...
  5. CallAdapter<T, R> callAdapter;
  6. public ServiceMethod build() {
  7. ...
  8. callAdapter = createCallAdapter();
  9. ...
  10. }
  11. }
  12. ...
  13. }

    在调用callAdapter的adapter()方法,其实就是把一个个Retrofit中的Call适配成其他平台也能使用的Call类型,比如咱们栗子中使用的是RxJava2CallAdapterFactory.create()来创建了一个RxJava2CallAdapter的适配器来适配RxJava2平台,适配成RxJava2平台能使用的Call。

    咱们接下来看Retrofit的CallAdapter接口中的Rxjava2CallAdapter实现类的adapter()方法:


 
 
  1. final class RxJava2CallAdapter implements CallAdapter<Object> {
  2. ...
  3. @Override public <R> Object adapt(Call<R> call) {
  4. Observable<Response<R>> responseObservable = new CallObservable<>(call);
  5. Observable<?> observable;
  6. ...
  7. return observable;
  8. }
  9. ...
  10. }

    可以看到,该适配方法返回了一个Observable被观察者对象。所以在咱们栗子中最后创建Retrofit的Call接口的实例对象时,也就创建了一个被观察者对象。

    最后,通过Retrofit的Call实现类,调用execute()方法,也就是调用okhttp3.Call的execute()方法来发送同步请求,请求结果同步返回;调用enqueue()方法,也就是调用okhttp3.Call的enqueue()方法来发送异步请求,请求结果通过Callback接口对象回调返回。

    至此,有关Retrofit2的源码分析结束。

 

六、总结

    咱们通过观察Retrofit2的源码发现Retrofit2代码量其实不多,但是有些童鞋看完整篇文章可能还一脸懵逼,这TM也太复杂了!其实不然,因为Retrofit2内部采用了大量的设计模式,导致咱们分析源码时候需要经常跳转着看源码,所以建议咱们在分析Retrofit2源码时候,一定要跟着流程仔细阅读源码,如果读懂了Retrofit2的流程,就会发现其实Retrofit2的整体框架还是挺简单的。

    最后再说一句,Retrofit2采用大量的设计模式是Retrofit2的精髓所在,完全可以借鉴到咱们的日常开发中,这才是咱们分析框架源码的初衷!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值