Retrofit2源码解析

Retrofit2源码解析

  • Retrofit实际上是一个网络请求框架的封装,它的核心是使用OkHttp来进行网络请求。
  • 完成OkHttp数据的转化和适配工作
  • Retrofit使用了动态代理

八个步骤

  1. 创建retrofit实例
  2. 定义网络请求接口,并添加注解
  3. 通过 动态代理 生成网络请求对象
  4. 通过 网络请求适配器 将网络请求对象 进行平台适配
  5. 通过 网络请求执行器(Call) 发送网络请求
  6. 通过 数据转换器 解析数据
  7. 通过 回调执行器 切换线程
  8. 在主线程处理返回结果

Method,ServiceMethod

private final Map<Method, ServiceMethod<?, ?>> serviceMethodCache = new ConcurrentHashMap<>();

  final okhttp3.Call.Factory callFactory;
  final HttpUrl baseUrl;
  final List<Converter.Factory> converterFactories;
  final List<CallAdapter.Factory> adapterFactories;
  final Executor callbackExecutor;
  final boolean validateEagerly;
  • Method就是网络请求的接口,ServiceMethod是解析接口上的注解后的实际网络请求方法,在Retrofit中用LinkedHashMap对ServiceMethod进行了缓存
public static final class Builder {
    private final Platform platform;
    private okhttp3.Call.Factory callFactory;
    private HttpUrl baseUrl;
    private final List<Converter.Factory> converterFactories = new ArrayList<>();
    private final List<CallAdapter.Factory> adapterFactories = new ArrayList<>();
    private Executor callbackExecutor;
    private boolean validateEagerly;

callbackExecutor

默认的回调执行器是采用handler.post的方式让回调在主线程中执行。

public static final class Builder {
    private final Platform platform;
    private okhttp3.Call.Factory callFactory;
    private HttpUrl baseUrl;
    private final List<Converter.Factory> converterFactories = new ArrayList<>();
    private final List<CallAdapter.Factory> adapterFactories = new ArrayList<>();
    private Executor callbackExecutor;
    private boolean validateEagerly;

Call

Retrofit中的Call对象跟Client的Call对象不一样,前置进行了封装。

Retrofit:

//An invocation of a Retrofit method that sends a request to a webserver and returns a response.
public interface Call<T> extends Cloneable {

  Response<T> execute() throws IOException;

  void enqueue(Callback<T> callback);

  boolean isExecuted();

  void cancel();

  boolean isCanceled();

  Call<T> clone();

  Request request();
}

OkHttp:

Converter

数据转换器,将返回的Response解析成一个Bean对象

CallAdapter

将Call接口适配成其他接口

源码分析

从create开始,它帮我们实例化了我们的服务端接口:

  public <T> T create(final Class<T> service) {
    Utils.validateServiceInterface(service);//验证
    if (validateEagerly) {
        //提前解析加载ServiceMethod,相当于缓存
      eagerlyValidateMethods(service); 
    }
    //返回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 {
            // 如果调用的是Object类的方法,则直接调用就行了
            if (method.getDeclaringClass() == Object.class) {
              return method.invoke(this, args);
            }
            if (platform.isDefaultMethod(method)) {
              return platform.invokeDefaultMethod(method, service, proxy, args);
            }

            //从缓存中取出ServiceMethod
            ServiceMethod<Object, Object> serviceMethod =
                (ServiceMethod<Object, Object>) loadServiceMethod(method);
            OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
            //把Call交给CallAdapter适配
            return
            serviceMethod.callAdapter.adapt(okHttpCall);
          }
        });
  }

这个Create实际上返回的是一个动态代理对象,当接口方法被调用时,会被动态代理拦截,然后调用InvocationHandler里的invoke方法,其中method就是调用的方法,args就是方法参数。

InvocationHandler会根据调用的接口里的方法,在缓存中取出解析后的ServiceMethod,然后构建一个OkHttpCall,最后交给CallAdapter进行适配,也就是将接口默认的方法返回值Call适配成其他类,比如RxJava的Observable。

对ServiceMethod进行了缓存:

  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;
  }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值