Retrofit源码简析

Retrofit相关时序图

Retrofit源码简析_第1张图片

创建Retrofit对象实例

通常使用Retrofit,如下:

Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("https://www.wanandroid.com/")
        .client(builder.build())
        .addConverterFactory(GsonConverterFactory.create())
        .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
        .build();

new Retrofit.Builder()

 

public Builder() {
  this(Platform.get());
}
Builder(Platform platform) {
  this.platform = platform;
  // 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());
}
Platform.get()
static Platform get() {
    return PLATFORM;
  }

PLATFORM

private static final Platform PLATFORM = findPlatform();

findPlatform()

private static Platform findPlatform() {
    try {
      Class.forName("android.os.Build");
      //目前是在Android里面应用,所以走的这个分支
      if (Build.VERSION.SDK_INT != 0) {
        return new Android();
      }
    } catch (ClassNotFoundException ignored) {
    }
    try {
      Class.forName("java.util.Optional");
      return new Java8();
    } catch (ClassNotFoundException ignored) {
    }
    return new Platform();
  }

new Android()

//Android类是继承自Platform的,重写了Platform的两个方法
static class Android extends Platform {
    @Override public Executor defaultCallbackExecutor() {
      return new MainThreadExecutor();
    }

    @Override CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {
      return new ExecutorCallAdapterFactory(callbackExecutor);
    }

    static class MainThreadExecutor implements Executor {
      //这里Handler初始化用的是getMainLooper(),说明此Handler最后是运行在UI线程的
      private final Handler handler = new Handler(Looper.getMainLooper());

      @Override public void execute(Runnable r) {
        handler.post(r);
      }
    }
  }

baseUrl这儿略过,只是设置一个基础的HttpUrl,不做深入研究。

client()方法:

    public Builder client(OkHttpClient client) {
      return callFactory(checkNotNull(client, "client == null"));
    }

    //在这里可能会有疑问,如果在new Retrofit.Builder对象的时候,没有调用Client方法,
    //那么岂不是没有可用于发送网络请求的OkHttpClient了?这个问题接着往下看会做解释
    public Builder callFactory(okhttp3.Call.Factory factory) {
      this.callFactory = checkNotNull(factory, "factory == null");
      return this;
    }

Client方法其实就是给Retrofit.Builder对象设置一个OkHttpClient对象,用于后续网络请求时使用,Retrofit其实就是对OkHttp的封装;在这里可能会有疑问,如果在new Retrofit.Builder对象的时候,没有调用Client方法,那么岂不是没有可用于发送网络请求的OkHttpClient了?这个问题接着往下看就会明白,其实是在Retrofit.Builder的build方法中,发现client为null的时候,就会new 一个OkHttpClient出来。

下面要上关键点了,主要看addCallAdatperFactory和addConvertFactory,搞清楚这两个东西的调用和来源,基本上Retrofit的原理就清晰很多了:

addCallAdatperFactory和addConvertFactory:

addCallAdatperFactory

private final List converterFactories = new ArrayList<>();
private final List adapterFactories = new ArrayList<>();   

public Builder addConverterFactory(Converter.Factory factory) {
    //把ConvertFactory添加到一个List集合中,集合会在Retrofit.Builder的build方法中被使用
    converterFactories.add(checkNotNull(factory, "factory == null"));
    return this;
}

public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
    //把CallAdatperFactory添加到一个List集合中,集合会在Retrofit.Builder的build方法中被使用
    adapterFactories.add(checkNotNull(factory, "factory == null"));
    return this;
}

接下来看Retrofit.Builder的build方法:

public Retrofit build() {
      if (baseUrl == null) {
        throw new IllegalStateException("Base URL required.");
      }

      okhttp3.Call.Factory callFactory = this.callFactory;
      //如果在调用build()方法之前,并没有调用client方法,那么在此处会new 一个OkHttpClient
      //用于后续做网络请求
      if (callFactory == null) {
        callFactory = new OkHttpClient();
      }

      Executor callbackExecutor = this.callbackExecutor;
      //默认的Executor是DefaultCallbackExecutor由于是在Android平台使用,
      //这里是Platformat的内部类Android里面重写的,
      /*static class Android extends Platform {
          @Override public Executor defaultCallbackExecutor() {
              return new MainThreadExecutor();
          }

        @Override CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {
          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);
          }
        }
      }*/
      //返回的是MainThreadExecutor,也就是说callbackExecutor,其实就是类MainThreadExecutor的对象实例
      //如果调用execute方法同步执行网络请求,那么就是执行的MainThreadExecutor的execute方法,通过创建UI线程的Handler对象,
      //将execute的任务post出来,然后执行。
      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));

      // Make a defensive copy of the converters.
      List converterFactories = new ArrayList<>(this.converterFactories);

      return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,
          callbackExecutor, validateEagerly);
    }
  }

到这里,Retrofit对象就创建完毕了,接下来该是生成请求接口对象实例了,一般都是调用Retrofit.create方法:

//生成网络请求接口实例
//这里需要思考一个问题,Java中Interface是没有办法实例化的,那么Retrofit是通过怎样的方式生成Interface实例对象的呢,答案就是动态代理
WanAndroidApi wanAndroidApi = retrofit.create(WanAndroidApi.class);

//Retrofit.java
public  T create(final Class service) {
    Utils.validateServiceInterface(service);
    if (validateEagerly) {
      eagerlyValidateMethods(service);
    }
    //通过动态代理返回网络请求接口对象实例
    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, Object[] args)
              throws Throwable {
            // If the method is a method from Object then defer to normal invocation.
            //如果调用的方法是Object类的方法,比如wait,toString,hashCode等,那么不做额外处理,直接调用返回
            if (method.getDeclaringClass() == Object.class) {
              return method.invoke(this, args);
            }
            //跟踪代码可知,platform的isDefaultMethod返回false,故此分支进不去
            /*
            boolean isDefaultMethod(Method method) {
                return false;
            }
            */
            if (platform.isDefaultMethod(method)) {
              return platform.invokeDefaultMethod(method, service, proxy, args);
            }
            //最终会执行loadServiceMethod方法
            ServiceMethod serviceMethod =
                (ServiceMethod) loadServiceMethod(method);
            OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
            return serviceMethod.callAdapter.adapt(okHttpCall);
          }
        });
  } 
  

看loadServiceMethod方法:

//Retrofit.java
ServiceMethod loadServiceMethod(Method method) {
    //如果缓存里面有,那么直接返回
    ServiceMethod result = serviceMethodCache.get(method);
    if (result != null) return result;

    synchronized (serviceMethodCache) {
      result = serviceMethodCache.get(method);
      //若缓存中没有当前method对应的对象(也就是ServiceMethod.Builder对象),new一个并将其添加到缓存
      if (result == null) {
        result = new ServiceMethod.Builder<>(this, method).build();
        serviceMethodCache.put(method, result);
      }
    }
    return result;
  }

接着看ServiceMehtod.Builder的build方法:

//ServiceMethod.java
public ServiceMethod build() {
      //创建生成CallAdapter
      callAdapter = createCallAdapter();
      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也就是Gson,xml等格式转换器
      responseConverter = createResponseConverter();

      for (Annotation annotation : methodAnnotations) {
        parseMethodAnnotation(annotation);
      }

      ......

      return new ServiceMethod<>(this);
    }

//ServiceMethod.java
private CallAdapter createCallAdapter() {
      //这里的method其实就是,当前调用自定义网络请求Interface中的方法
      //returnType就是当前方法的返回值类型,比如Call、Obserable等
      Type returnType = method.getGenericReturnType();
      if (Utils.hasUnresolvableType(returnType)) {
        throw methodError(
            "Method return type must not include a type variable or wildcard: %s", returnType);
      }
      //如果没有返回是,也就是void,抛出异常
      if (returnType == void.class) {
        throw methodError("Service methods cannot return void.");
      }
      //获取当前调用方法的注解,比如@GET、@POST、@MultiPart等
      Annotation[] annotations = method.getAnnotations();
      try {
        //noinspection unchecked
        //调用retrofit的callAdapter方法生成CallAdapter对象
        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.java
public CallAdapter callAdapter(Type returnType, Annotation[] annotations) {
    return nextCallAdapter(null, returnType, annotations);
}

public CallAdapter nextCallAdapter(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;
      }
    }
    ......
    throw new IllegalArgumentException(builder.toString());
  }

注意

在nextCallAdapter方法中,这里的adapterFactories,就是创建Retrofit对象的时候会调用addCallAdapterFactory方法,在addCallAdapterFactory方法中,会将添加的CallAdapterFactory对象,添加到adapterFactories这个list中

 public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
      adapterFactories.add(checkNotNull(factory, "factory == null"));
      return this;
    }

那么有个疑问,如果在调用Retrofit.Builder的build方法之前没有调用addCallAdapterFactory方法,adapterFactories岂不是为null了,其实如果adapterFactories为null,那么会在Retrofit.Builder的build方法中添加默认的,在build方法中,有如下代码段:

    // Make a defensive copy of the adapters and add the default Call adapter.
      List adapterFactories = new ArrayList<>(this.adapterFactories);
      //在此处,不论在build之前有没有调用addCallAdapterFactory方法,此处都会再添加一个默认CallAdapter
      adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));

      // Make a defensive copy of the converters.
      List converterFactories = new ArrayList<>(this.converterFactories);
      //new Retrofit对象的时候会将新创建的adapterFactories传入,所以不用担心没有初始化的问题
      return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,
          callbackExecutor, validateEagerly);

那么接着来看nextCallAdapter方法,在for循环中返回了CallAdapter对象,如下面代码段:

//Retrofit.java,nextCallAdapter方法
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;
      }
    }

从前面代码可知:在callAdapter方法中调用nextCallAdpater,

public CallAdapter callAdapter(Type returnType, Annotation[] annotations) {
  return nextCallAdapter(null, returnType, annotations);
}

nextCallAdapter第一个参数为null,说明skipPast为null,那么int start = adapterFactories.indexOf(skipPast) + 1;start的值为0,因为adapterFactories这个列表中并没有null对象,所以adapterFactories.indexOf(skipPast)的值为-1,-1+1=0,所以start值为0

所以for循环中i值其实是从0开始的,接下来就分为两种情况了:

1,在调用Retrofit.Builder的build方法之前,就已经调用了addAdapterFactory方法添加了Adapter,那么adapterFactories这个list中的第一个元素,也就是下标为0的元素(也就是adapterFactories.get(0)),就是调用addAdapterFactory添加的Adapter,比如像文章开头处创建Retrofit的方式:

Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("https://www.wanandroid.com/")
        .client(builder.build())
        .addConverterFactory(GsonConverterFactory.create())
        .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
        .build();

那么这里的adapterFactories.get(0)就是RxJava2CallAdapterFactory.create()。

接下来,看下如果添加了调用了addAdapterFactory方法,在创建Retrofit对象的时候调用如下方法:addCallAdapterFactory(RxJava2CallAdapterFactory.create()):

在Retrofit的create方法的动态代理中,最终返回的的是return serviceMethod.callAdapter.adapt(okHttpCall);看下这个流程:serviceMethod.callAdapter是CallAdapter 类型对象,前面已经讲过,callAdapter的初始化是在createCallAdapter()中,最终会调用到Retrofit.java的nextCallAdapter方法,CallAdapter adapter = adapterFactories.get(i).get(returnType, annotations, this);

我们知道此处的adapterFactories这个list中获取的第一个不为null的CallAdapterFactory对象,就是我们自己通过addCallAdapterFactory添加的RxJava2CallAdapterFactory。

RxJava2CallAdapterFactory.create方法返回的对象是RxJava2CallAdapterFactory,然后RxJava2CallAdapterFactory的get方法返回的是RxJava2CallAdapter对象,接着看RxJava2CallAdapter的adapt方法,最终返回的就是Obserable,这就是Rxjava的Obserable被观察者。

有了Obserable对象,就可以调用Rxjava中Observer的observer方法和subscribeOn等方法,实现UI线程回调网络请求线程。

2,在调用Retrofit.Builder的build方法之前,没有调用addAdapterFactory,那么那么adapterFactories这个list中的第一个元素,就是在build方法中添加的platform.defaultCallAdapterFactory(callbackExecutor)

adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));

在nextCallAdapter的for循环中,如果拿到第一个Adapter,那么就直接return了,后续Adapter就是用的此处返回的。

默认的CallAdapter 是如下流程:

platform.defaultCallAdapterFactory(callbackExecutor)--》new ExecutorCallAdapterFactory(callbackExecutor);--》ExecutorCallAdapterFactory的get方法,get方法中return的时候,new CallAdapter,new 出来的CallAdapter重写了adapt方法,adapt方法返回new ExecutorCallbackCall<>(callbackExecutor, call);--》ExecutorCallbackCall是继承自Call的,它里面分别实现了同步请求execute方法和异步请求enqueue方法。

这里注意

同步请求execute方法是用了静态代理,delegate.execute最终会转到,前面提到的Create方法里面动态代理的最后new 出来的OkHttpCall里面的execute()方法--》createRawCall()--》serviceMethod.callFactory.newCall,这里serviceMethod.callFactory就是okhttp3.Call.Factory--》builder.retrofit.callFactory(),这就是OkHttpClient,调用OkHttpClient的newCall方法执行网络请求。

异步请求enqueue方法中,也用了静态代理:

delegate.enqueue(new Callback() {
  @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);
        }
      }
    });
  }

这里的callbackExecutor其实就是前面提到的Platform的内部类Android中的MainThreadExecutor

static class Android extends Platform {
  @Override public Executor defaultCallbackExecutor() {
    return new MainThreadExecutor();
  }

  @Override CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {
    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);
    }
  }
}

delegate.enqueue也是最终转到OkHttpCall中的enqueue方法(跟同步的execute是同样的),最终调用OkHttpclient的newCall方法执行请求。

callbackExecutor.execute执行的就是MainThreadExecutor的execute方法,Handler是初始化在main线程的,这儿就理解了回调为什么会在UI线程。

addConverterFactory

在Retrofit.Builder的构造方法中,会首先添加一个默认的ConvertFactory,converterFactories.add(new BuiltInConverters());

如果调用addConvertFactroy方法添加了ConvertFactory,也会将这些ConvertFactory添加到converterFactories这个list中

那么在Retrofit.Builder的build方法中,在new Retrofit的时候传入这个converterFactories,

ConvertFactory的流程比较简单,这里就不仔细展开说明了。

就是在Retrofit的requestBodyConverter和reponseBodyConverter中,分别会调用nextRequestBodyConverter和nextResponseBodyConverter方法,这两个next方法中会获取converterFactories这个list中添加的Convert.Factory对象,具体的调用是在ServiceMethod的toResponse中调用;ServiceMethod的toResponse方法是在OkHttpCall的parseResponse方法中调用的,而parseResponse分别在OkHttpCall的enqueue和execute两个方法的参数Callback中的onResponse中调用的,也就是说,在onResponse方法回调的时候,就将返回的数据流序列化为java对象了。

结束。

 

 

你可能感兴趣的:(Retrofit源码简析)