安卓轮子之Retrofit源码赏析

Retrofit 中 Service 接口的实现

对于自定义 Service 类:

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

使用时:

GithubService githubService = retrofit.create(GithubService.class);
MyCall<String> call = githubService.listRepos("xiangaoole");

我们看一下 create 源码:

// Retrofit.java
@SuppressWarnings("unchecked")
public <T> T create(final Class<T> 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, @Nullable Object[] args)
            throws Throwable {
          // 调用的是 Object 方法
          if (method.getDeclaringClass() == Object.class) {
            return method.invoke(this, args);
          }
          // 调用的是默认方法
          if (platform.isDefaultMethod(method)) {
            return platform.invokeDefaultMethod(method, service, proxy, args);
          }
          // 调用的是接口的方法
          ServiceMethod<Object, Object> serviceMethod =
              (ServiceMethod<Object, Object>) loadServiceMethod(method);
          OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
          return serviceMethod.adapt(okHttpCall);
        }
      });
}

create() 方法最终返回的就是 GithubService 接口的代理。在调用 listRepos() 方法时,loadServiceMethod() 方法加载一个 ServiceMethod 对象,在创建过程中完成对接口方法的解析,也就是解析方法注解,同时从 retrofit 的 CallAdapterFactory 集合和 ConverterFactory 集合中选择类型匹配的保存在成员变量 callAdapter 和 responseConverter 中。最后调用 callAdapter 的 adapt(Call call) 方法来执行 OkHttpCall。

这里的 callAdapter 是从 retrofit 对象的 CallAdapterFactory 集合中找到和接口方法的返回值匹配的元素,进而创建的 CallAdapter 实例。

没有设置 CallAdapterFactory 时,默认的 callAdapter 是 ExecutorCallAdapter,执行 adapt() 方法返回对象类型为 ExecutorCallbackCall。

我们的例子中,设置了自定义的 MyCallAdapter.Factory,动态代理调用 listRepo 方法时,最终调用 MyCallAdapter 的 adapt(Call call) 方法,返回我们自定义的 MyCall 对象。

网络请求的发送

默认CallAdapter

没有添加自定义 CallAdapter.Factory 时,采用默认的 ExecutorCallbackCall 发送网络请求。ExecutorCallbackCall 的 execute()enqueue() 方法,委托真实对象 retrofit2.OkHttpCall 来执行。

static final class ExecutorCallbackCall<T> implements Call<T> {
    final Executor callbackExecutor;
    final Call<T> delegate; // 真实对象

    ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) {
        this.callbackExecutor = callbackExecutor;
        this.delegate = delegate;
    }

    ...
}

同步提交:

@Override public Response<T> execute() throws IOException {
  return delegate.execute();
}

异步提交:

@Override public void enqueue(final Callback<T> callback) {
  checkNotNull(callback, "callback == null");

  delegate.enqueue(new Callback<T>() {
    @Override public void onResponse(Call<T> call, final Response<T> 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<T> call, final Throwable t) {
      callbackExecutor.execute(new Runnable() {
        @Override public void run() {
          callback.onFailure(ExecutorCallbackCall.this, t);
        }
      });
    }
  });
}

最后都会调用 parseResponse() 方法,调用 StringCallAdapter 的 adapt() 方法将 ResponseBody 转化为 String。

// retrofit2.OKHttpCall
Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
    ...
    T body = serviceMethod.toResponse(catchingBody);
    ...
}

// retrofit2.ServiceMethod<R, T>
R toResponse(ResponseBody body) throws IOException {
  return responseConverter.convert(body);
}

猜你喜欢

转载自blog.csdn.net/weixin_40255793/article/details/81589998