Retrofit执行原理详解

 
 val retrofit =  Retrofit.Builder()
      .baseUrl("https://api.device.cn/")
      .callFactory(OkHttpClient())
      .addConverterFactory(GsonConvertFactory.create())
      //.addCallAdapterFactory(RxJavaCallAdapterFactory.create())  
      //.addCallAdapterFactory(HiCallAdapterFactory.create())
      .build();
  
 interface Api {
   //默认情况下方法返回类型为Call<T>,response类型为ResponseBody
   @GET("/user/detail") 
   fun userDetail(): Call<ResponseBody>
 }

 Call<User> caller= retrofit.create(Api.class).userDetail();
 caller.enqueue(new Callback(){...});

Retrofit执行原理简述

Retrofit执行原理是,通过执行内部方法create作为接口请求的起始。进入通过执行动态代理生成接口对象,调用接口对象方法并回调动态代理的invoke方法。在回调invoke方法过程中,会解析接口对象方法的注解、方法参数注解、方法返回值类型并将解析内容封装成对象。待执行到ServiceMethod.invoke()时,Call对象执行同步/异步请求,使得okhttp的拦截器BridgeIntercdeptor通过chain.proceed(requestBuilder.build())传入request对象(通过已解析的注解内容所生成),然后执行最终的接口数据请求,并返回响应报文。

在这里插入图片描述

在这里插入图片描述

Retrofit执行源码拆解

在执行Retrofit.Builder()…build();方法build时,生成Retrofit对象过程中,
若callFactory我们未指定则默认使用OkHttpClient。
若callbackExecutor未指定则默认使用Handler。
若CallAdapterFactory未指定则默认使用DefaultCallAdapterFactory(使得响应报文,返回类型默认是Call<ResponseeBody>

retrofit.create(Api.class)

在retrofit执行到方法create时,通过动态代理类获取到Api接口实例。在执行动态代理前会先判断该传入的Api.class是否是接口类型validateServiceInterface(service);,否则抛出异常。

retrofit.create(Api.class).userDetail()

在retrofit执行到方法userDetail时,则是通过接口Api实例对象执行方法userDetail()。此时会回调动态代理的方法invoke()。在invoke方法中
1,如果方法是来自Object的方法,则直接调用method.invoke(this, args)
2,如果方法是默认方法,则platform.invokeDefaultMethod(method, service, proxy, args)
3,反之,执行loadServiceMethod(method).invoke(args != null ? args : emptyArgs);

在执行到loadServiceMethod(method),进入ServiceMethod.java类中。即对Api接口的userDetail()方法注解、方法参数注解及返回值类型进行解析,并获得CallAdapter实例。解析的具体实现,体现在RequestFactory.parseAnnotations(retrofit, method);方法中。解析完成后封装解析内容在类RequestFactory中。之后继续执行HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);目的是使用RequestFactory得到CallAdapter<ResponseT, ReturnT>的实例对象callAdapter。


// ServiceMethod.java
abstract class ServiceMethod<T> {
  static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
  	// 注解解析
    RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);
    ... ...
    // 获得CallAdapter对象实例
    return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
  }

}

获得callAdappter实例后,获取实例源码如下


// HttpServiceMethod.java
static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
      Retrofit retrofit, Method method, RequestFactory requestFactory) {
	......
	// 获得callAdapter实例
	CallAdapter<ResponseT, ReturnT> callAdapter =
        createCallAdapter(retrofit, method, adapterType, annotations);
        .... .....
	// 创建HttpServiceMethod的实现类,并作为CallAdapter的代理类。替代CallAdapter。
	if (!isKotlinSuspendFunction) {
      return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
    } 
}

接下来,在Retrofit.java的create方法中,会执行loadServiceMethod(method).invoke(args != null ? args : emptyArgs)中的invoke(args != null ? args : emptyArgs)方法。使用多态方式,形式上是执行了ServiceMethod.invoke(args != null ? args : emptyArgs),实际是其实现类CallAdapted.invoke(args != null ? args : emptyArgs)在执行。之后顺着逻辑进入HttpServiceMethod#invoke方法中

@Override final @Nullable ReturnT invoke(Object[] args) {
   Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
   return adapt(call, args);
}

会发现,在invoke方法中通过OkHttpCall创建了Call的实例对象。创建Call实例目的是干啥?是为通过Call做网络请求的!之后会由HttpServiceMethod#invoke方法进入CallAdapted#invoke方法,执行callAdapter.adapt(call)。默认情况下,执行流程会进入DefaultCallAdapterFactory类中。执行类中匿名内部类的adapt方法。终,返回了一个Call代理类ExecutorCallbackCall(或者说是实现类)实例,为后面执行网络请求(如enqueue(final Callback callback))做铺垫。


// DefaultCallAdapterFactory.java
final class DefaultCallAdapterFactory extends CallAdapter.Factory {
 ... ........
  @Override public @Nullable CallAdapter<?, ?> get(
      Type returnType, Annotation[] annotations, Retrofit retrofit) {
    . .... ...
    return new CallAdapter<Object, Call<?>>() {
      @Override public Type responseType() {
        return responseType;
      }
	// 默认情况下,执行流程会进入DefaultCallAdapterFactory的匿名内部类的adapt方法
      @Override public Call<Object> adapt(Call<Object> call) {
        return executor == null // 默认非空,是Handler
            ? call
            : new ExecutorCallbackCall<>(executor, call);
      }
    };
  }

caller.enqueue(new Callback(){…})

在retrofit执行到方法enqueue时,即是拿ExecutorCallbackCall实例,调用其enqueue方法,发起网络请求并获得响应报文。然后将响应报文的回调切换到UI线程。

// ExecutorCallbackCall.java 为 Call.java的代理类
static final class ExecutorCallbackCall<T> implements Call<T> {
  ... ...
    ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) {
      this.callbackExecutor = callbackExecutor;
      this.delegate = delegate;
    }

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

      delegate.enqueue(new Callback<T>() {// Call执行异步请求
        @Override public void onResponse(Call<T> call, final Response<T> response) {
          callbackExecutor.execute(() -> {// 通过Handler切换线程到UI线程
            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);// 回调响应报文给用户
            }
          });
        }
       ... ...
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值