本文基于 Retrofit 2.5

Retrofit :改造
改造了什么呢?
把一个 Http 请求转化为一个 Java 接口的调用。

文章目录

  • 一、简单使用
  • 二、一次调用
    • 2.1 InvocationHandler.invoke()
      • 2.1.1 创建 ServiceMethod
        • 2.1.1.1 创建 requestFactory
        • 2.1.1.2 创建 callFactory
        • 2.1.1.3 创建 callAdapter
        • 2.1.1.4 创建 responseConverter
      • 2.1.2 执行 ServiceMethod 的 invoke 方法
        • 2.1.2.1 创建 OkHttpCall
        • 2.1.2.2 callAdapter.adapt()
      • 2.1.3 添加 GsonConverter
      • 2.1.4 添加 RxJava2CallAdapter
  • 三、整体流程
  • 四、一些问题
  • 五、借鉴学习
    • 5.1 动态生成接口的实现类
    • 5.2 工厂模式

一、简单使用

这是官网给的例子(http://square.github.io/retrofit/)。

定义 Service 接口,该接口内的方法就是 api 调用。

public interface GithubService {    @GET("users/{user}/repos")    Call<List<Repo>> listRepos(@Path("user") String user);}

创建 Retrofit 对象,并通过 Retrofit 对象再创建 Service 接口实现类的对象。

Retrofit retrofit = new Retrofit.Builder()    .baseUrl("https://api.github.com/")    .build();GithubService githubService = retrofit.create(GithubService.class);

调用 Serice 对象的方法,发起网络请求。

Call<List<Repo>> repos = githubService.listRepos("gdeeer");

二、一次调用

从这句开始。

Call<List<Repo>> repos = githubService.listRepos("gdeeer");

点进去,发现找不到 listRepos 的实现。因为 githubService 的类是动态生成的,我们看不到类的实现。

只能去看下生成 githubService 对象的代码。

GithubService githubService = retrofit.create(GithubService.class);

2.1 InvocationHandler.invoke()

看 Retrofit 的 create() 方法。

public <T> T create(final Class<T> service) {  ...  return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },      new InvocationHandler() {        ...        @Override public Object invoke(Object proxy, Method method, @Nullable Object[] args)            throws Throwable {          ...          return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);        }      });}

可以看到,Retrofit 是通过 Proxy.newProxyInstance 来生成 GithubService 接口的实现类的,而接口内方法的处理逻辑就在 InvocationHandler 的 invoke() 中(更多关于Proxy.newProxyInstance 的内容可见Java 基础:静态代理和动态代理)。

invoke() 方法中执行了 loadServiceMethod(method).invoke(args)。所以 githubService.listRepos("gdeeer"); 方法的真正调用,就是在这里进行的。

2.1.1 创建 ServiceMethod

看一下 loadServiceMethod 方法。

ServiceMethod<?> loadServiceMethod(Method method) {  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.parseAnnotations() 来新建,并放入缓存。

abstract class ServiceMethod<T> {  static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {    RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);    ...    return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);  }  abstract T invoke(Object[] args);}

ServiceMethod 是一个抽象类,只有一个方法 invoke(),ServiceMethod.parseAnnotations() 相当于一个工厂,用来创建 ServiceMethod 对象,它内部又调用了 HttpServiceMethod.parseAnnotations() 来创建。

static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(    Retrofit retrofit, Method method, RequestFactory requestFactory) {  CallAdapter<ResponseT, ReturnT> callAdapter = createCallAdapter(retrofit, method);  ...  Converter<ResponseBody, ResponseT> responseConverter =      createResponseConverter(retrofit, method, responseType);  okhttp3.Call.Factory callFactory = retrofit.callFactory;  return new HttpServiceMethod<>(requestFactory, callFactory, callAdapter, responseConverter);}

终于出现了 new HttpServiceMethod(),HttpServiceMethod 是 ServiceMethod 的实现类,它接收4个参数:requestFactory、callFactory、callAdapter、responseConverter。

requestFactory 用来生成 okhttp3.Request,okhttp3.Request 代表一次 Http 请求。

callFactory 用来生成 okhttp3.Call,okhttp3.Call 代表一个准备好了的 Request。

callAdapter 用来处理 retrofit2.Call,retrofit2.Call 是 Retrofit 中定义的 Call,与 okhttp3.Call 基本一致,最终执行的还是 okhttp3.Call。

responseConverter 用来转化一个 response。

2.1.1.1 创建 requestFactory

ServiceMethod.parseAnnotations() 方法中会创建 requestFactory。

// ServiceMethod.javastatic <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {  RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);  ...}// RequestFactory.javastatic RequestFactory parseAnnotations(Retrofit retrofit, Method method) {  return new Builder(retrofit, method).build();}

通过 RequestFactory.Builder 来创建一个 RequestFactory。

2.1.1.2 创建 callFactory

HttpServiceMethod 的 parseAnnotations() 方法中会创建 callFactory。

创建方式是直接使用 Retrofit 类的 callFactory。

static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(...) {  okhttp3.Call.Factory callFactory = retrofit.callFactory;  ...}

Retrofit 中的 callFactory 在 Retrofit.Builder.build() 时初始化。没有指定的话,默认就是一个 OkHttpClient

// Retrofit#Builder.javapublic Retrofit build() {  ...  okhttp3.Call.Factory callFactory = this.callFactory;  if (callFactory == null) {    callFactory = new OkHttpClient();  }  ...}

2.1.1.3 创建 callAdapter

HttpServiceMethod 的 parseAnnotations() 方法中会创建 callAdapter。

创建方式是通过 Retrofit 类,Retrofit 会遍历自己的 callAdapterFactories,找到合适的 CallAdaperFactory,如果找不到,会抛异常。

什么是合适的 CallAdaperFactory,就是能产生合适的 CallAdaper 的 Factory。什么是合适的 CallAdapter,就是能 Call 改编为指定的 returnType 的 CallAdapter。

CallAdapter 将 Call 改编(adapt into)为 T。

// HttpServiceMethod.javastatic <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(...)(CallAdapter<ResponseT, ReturnT> callAdapter = createCallAdapter(retrofit, method);...}private static <ResponseT, ReturnT> CallAdapter<ResponseT, ReturnT> createCallAdapter(...) {    ...    return (CallAdapter<ResponseT, ReturnT>) retrofit.callAdapter(returnType, annotations);    ...}// Retrofit.javapublic CallAdapter<?, ?> callAdapter(...) {  return nextCallAdapter(null, returnType, annotations);}public CallAdapter<?, ?> nextCallAdapter(...) {  ...  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;    }  }  ...}

Retrofit 中的 callAdapterFactories 在 Retrofit.Builder.build() 时初始化。

// Retrofit#Builder.javapublic Retrofit build() {  ...  Executor callbackExecutor = this.callbackExecutor;  if (callbackExecutor == null) {    callbackExecutor = platform.defaultCallbackExecutor();  }  List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);  callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));  ...}

初始化时,根据所在的不同平台,会添加不同的默认工厂。

  • Android 平台上,callbackExecutor 是 MainThreadExecutor。若当前机器的 Android 版本号大于 24,会添加 CompletableFutureCallAdapterFactory、ExecutorCallAdapterFactory。若小于等于 24,只添加一个 ExecutorCallAdapterFactory。

  • Java8 平台上,callbackExecutor 是 null。会添加 CompletableFutureCallAdapterFactory、 DefaultCallAdapterFactory。

DefaultCallAdapterFactory 只能生产 DefaultCallAdapter,它将 Call 改编为 Call(它自己)。

ExecutorCallAdapterFactory 只能生产 ExecutorCallAdapter,它将 Call 改编为 ExecutorCallbackCall(也是一个 Call)。

CompletableFutureCallAdapterFactory 只能生产 CompletableFutureCallAdapter(实际上是 BodyCallAdapter、ResponseCallAdapter),它将 Call 改编为 CompletableFuture

2.1.1.4 创建 responseConverter

HttpServiceMethod 的 parseAnnotations() 方法中会创建 callAdapter。

创建方式是通过 Retrofit 类,Retrofit 会遍历自己的 converterFactories,找到合适的 ConverterFactory,如果找不到,会抛异常。

什么是合适的 ConverterFactory,就是能生产合适的 Converter 的 Factory。什么是合适的 Converter,就是能将 ResponseBody 转化为指定 returnType 的 Converter。

Converter,将 F 转化为 T。(这里的 F,一般就是 ResponseBody)

// HttpServiceMethod.javastatic <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(...) {  ...  Converter<ResponseBody, ResponseT> responseConverter =    createResponseConverter(retrofit, method, responseType);  ...}private static <ResponseT> Converter<ResponseBody, ResponseT> createResponseConverter(...) {  ...  return retrofit.responseBodyConverter(responseType, annotations);  ...}// Retrofit.javapublic <T> Converter<ResponseBody, T> responseBodyConverter(Type type, Annotation[] annotations) {  return nextResponseBodyConverter(null, type, annotations);}public <T> Converter<ResponseBody, T> nextResponseBodyConverter(...) {  ...  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) {      return (Converter<ResponseBody, T>) converter;    }  }  ...}

Retrofit 中的 converterFactories 在 Retrofit.Builder.build() 时初始化。

// Retrofit#Builder.javapublic Retrofit build() {  ...  List<Converter.Factory> converterFactories = new ArrayList<>(      1 + this.converterFactories.size() + platform.defaultConverterFactoriesSize());  converterFactories.add(new BuiltInConverters());  converterFactories.addAll(this.converterFactories);  converterFactories.addAll(platform.defaultConverterFactories());  ...}

初始化时,根据所在的不同平台,会添加不同的默认工厂。

  • Android 平台上,只会添加 BuiltInConverters。

  • Java8 平台上,会添加 BuiltInConverters、OptionalConverterFactory。

BuiltInConverters:

@Override public @Nullable Converter<ResponseBody, ?> responseBodyConverter(    Type type, Annotation[] annotations, Retrofit retrofit) {  if (type == ResponseBody.class) {    return Utils.isAnnotationPresent(annotations, Streaming.class)        ? StreamingResponseBodyConverter.INSTANCE        : BufferingResponseBodyConverter.INSTANCE;  }  if (type == Void.class) {    return VoidResponseBodyConverter.INSTANCE;  }  if (checkForKotlinUnit) {    try {      if (type == Unit.class) {        return UnitResponseBodyConverter.INSTANCE;      }    } catch (NoClassDefFoundError ignored) {      checkForKotlinUnit = false;    }  }  return null;}

它只能生产可以将 ResponseBody 转化为:ResponseBodyVoidUnit 的 Converter,如果指定的 returnType 不是这几种,就会返回 null。

OptionalConverterFactory:

@Override public @Nullable Converter<ResponseBody, ?> responseBodyConverter(    Type type, Annotation[] annotations, Retrofit retrofit) {  if (getRawType(type) != Optional.class) {    return null;  }  Type innerType = getParameterUpperBound(0, (ParameterizedType) type);  Converter<ResponseBody, Object> delegate =      retrofit.responseBodyConverter(innerType, annotations);  return new OptionalConverter<>(delegate);}

它只能生产 OptionalConverter,它将 ResponseBody 转化为 Optional,如果指定的 returnType 不是 Optional,就会返回 null。

2.1.2 执行 ServiceMethod 的 invoke 方法

2.1.2.1 创建 OkHttpCall

获取到 HttpServiceMethod 对象后,就会调用它的 invoke 方法。

@Override ReturnT invoke(Object[] args) {  return callAdapter.adapt(      new OkHttpCall<>(requestFactory, args, callFactory, responseConverter));}

里面通过 requestFactory、callFactory、responseConverter 生成了一个 OkHttpCall 对象,CallAdapter 处理的就是它。

OkHttpCall 是 Retrofit2.Call 的实现类,它会包含一个 okhttp3.Call 的对象 rawCall,rawCall 通过 callFactory、requestFactory 创建。

okhttp3.Call rawCall = callFactory.newCall(requestFactory.create(args));

2.1.2.2 callAdapter.adapt()

接下来看 callAdapter 的 adapt() 方法。

adapt() 方法在 retrofit 包中,有四处实现。即包中定义了四个 CallAdapter,DefaultCallAdapter、ExecutorCallAdapter、BodyCallAdapter、ResponseCallAdapter。

DefaultCallAdapter 将 Call 改编为 Call。
ExecutorCallAdapter 将 Call 改编为 ExecutorCallbackCall(也是一个 Call)。
BodyCallAdapterResponseCallAdapter 将 Call 改编为 CompletableFuture(Java8 中的类)。

我们再回头看下最开始的代码。

Call<List<Repo>> repos = githubService.listRepos("gdeeer");

实际运行后,发生了异常。

异常发生在 HttpServiceMethod.createResponseConverter() 方法中,即生产 Converter 的方法中。

如上面 2.1.1.4 中所说,生产 Converter 时,会遍历 Retrofit 中的 converterFactories,如果没有找到合适的 ConverterFactory,就会抛出异常。

默认的 converterFactories,只能生产 returnType 是 ResponseBodyVoidUnitOptional 的 converter。但我们的 listRepos() 方法的 returnType 是 Call>,所以它会返回 null。

2.1.3 添加 GsonConverter

系统内置的 ConverterFactory 不满足需求,我们只能自己创建新的 ConverterFactory。

官方文档上说,Retrofit 默认只支持将 HTPP bodies 转为 ResponseBody。如果要支持其他类型,需要使用新的 Converter,并提供了几种 Converter 库。

我们使用 GsonConverter 来转化,引入 converter-gson 库后,修改 Retrofit 的 build 代码。

Retrofit retrofit = new Retrofit.Builder()    .baseUrl("https://api.github.com/")    .addConverterFactory(GsonConverterFactory.create())    .build();

现在代码就可以正常运行了。

2.1.4 添加 RxJava2CallAdapter

implementation 'com.squareup.retrofit2:adapter-rxjava2:2.5.0'

RxJava2CallAdapter 将 Call 改编为一个 Observable。

Observable subscribe 时,会执行 Call,在 onNext 中回调。

三、整体流程

上面的目录已经很清楚,总结一下就是:

  1. 生成 ServiceMethod
  2. 调用 ServiceMethod.invoke
    1. 生成 CallAdapter、OkHttpCall
    2. 通过 CallAdapter 调用 OkHttpCall

四、一些问题

  • 为什么 HttpServiceMethod 的四个构造参数中,requestFactory 是在 ServiceMethod.parseAnnotations 时生成,而其他参数是在 HttpServiceMethod.parseAnnotations 时生成?

应该是开发者觉得以后还有除了 HttpServiceMethod 以外的 ServiceMethod 实现类,但是他们都需要 requestFactory,所以放在调用 HttpServiceMethod.parseAnnotations 之前生成。

  • 为什么 ServiceMethod 持有的对象,requestFactory、callFactory 使用的是 Factory,而 callAdatper、responseConverter 使用的 Factory 生产的产品?

因为 CallAdatper、ResponseConverter 对于每个方法来说,不管调用几次,它们的值都不变,但对于 Request、Call 来说,每次调用,都要产生不同的对象。

  • 为什么 Retrofit 要新定义一个 retrofit2.Call,而不直接使用 okhttp3.Call?为什么没有一个 retrofit2.Request?

实现 retrofit2.Call 接口的有两个类,一个是代理了 okhttp3.Call 的 OkHttpCall 类,另一个是代理了另一个 retrofit2.Call 的 ExecutorCallbackCall 类。

ExecutorCallbackCall 会把 retrofit2.Call 的 execute()、enqueue() 方法都放到 Executor 中执行。

  • RequestFactory、CallFactoty、CallAdapterFactory、ConverterFactory 都在哪里生成?他们的产品都在哪里生成(Factory 在哪里使用)?他们的产品在哪里使用?

RequestFactory 在 ServiceMethod.parseAnnotations 中生成。

Request 在 OkHttpCall.createRawCall 中生成并使用,用来生成 okhttp3.Call。

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;}

CallFactory 在 Retrofit.Builder.build() 方法中生成(即 OkHttpClient)。

Call 在 OkHttpCall.createRawCall 中生成并使用,用来生成 okhttp3.Call(会委托 OkHttpCall 调用它的方法)。OkHttpCall.createRawCall 在 OkHttpCall 执行方法时调用。

OkHttpCall 在 HttpServiceMethod.invoke 方法中生成。用户调用 api 方法后,获得 CallAdapter.adapt 生成的对象,再调用该对象的方法时使用。

CallAdapterFactory 在 Retrofit.Builder.build() 方法中生成。

CallAdapter 在 ServiceMethod.parseAnnotations 中生成,在用户调用 api 方法时使用。

ConverterFactory 在 Retrofit.Builder.build() 方法中生成。

Converter 在 ServiceMethod.parseAnnotations 中生成,在 OkHttpCall.executeOkHttpCall.enqueue 时使用。

五、借鉴学习

5.1 动态生成接口的实现类

5.2 工厂模式

更多相关文章

  1. Android(安卓)6.0关于权限的问题
  2. Android面试题(25)-Bundle机制
  3. Android中调用系统摄像并且保存到指定位置的一些问题&Uri转文件
  4. Android(安卓)Binder机制(3) 本地服务注册过程
  5. Android(安卓)程序获取、设置铃声音量
  6. 【Android(安卓)开发教程】理解Intent对象
  7. Parcelable使用(跨进程,Intent传输)
  8. Android(安卓)View,ViewGroup 事件分发
  9. GetSystemService的详解

随机推荐

  1. Android(安卓)Handler机制4之Looper与Han
  2. android 应用移植到ophone 平台需注意
  3. Android(安卓)JNI简单实例(android 调用C/
  4. 基于NDK的Android防破解& Android防破解
  5. 安卓textview edittext 中inputType的类
  6. Android中EditText的inputType属性(键盘类
  7. TextView过长显示省略号, TextView文字中
  8. Android(安卓)RelativeLayout 属性
  9. Android(安卓)JNI简单实例(android 调用C/
  10. listview android:cacheColorHint,androi