Retrofit面试题系列

序、慢慢来才是最快的方法。

Retrofit 是一个 RESTful 的 HTTP 网络请求框架的封装,网络请求的工作本质上是 OkHttp 完成。对接口返回的对象通过addCallAdapterFactory转换成想要的类型,经常使用的是就是RxJavaCallAdapterlFactory,对请求结果通过addConverterFactory转换成想要的类型,经常的使用的是GsonConverterFactory。

问1:什么是动态代理?

动态代理和静态代理都属于代理模式,动态代理是可以在运行期动态创建某个interface的实例,我们通过Proxy.newProxyInstance产生的代理类,当调用接口的任何方法时,都会被InvocationHandler#invoke方法拦截,同时,在这个方法中可以拿到所传入的参数等,依照参数值再做相应的处理。

问2:Retrofit是如何将子线程切换到主线程?

在添加默认适配器工厂defaultCallAdapterFactories时,将callbackExecutor作为了一个参数,那么它的具体实现也就是在这个默认适配器工厂中。 我们来看下callbackExecutor在里面做了些啥。

static final class ExecutorCallbackCall<T> implements Call<T> {
    final Executor callbackExecutor;
    final Call<T> delegate;
    ...

    @Override
    public void enqueue(final Callback<T> callback) {

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

在上述代码里了解到,callbackExecutor即Executor,一个线程调度器。在Call的enqueue实现里执行了一个异步网络请求delegate.enqueue,在请求的响应onResponse、onFailure中 Executor也同样执行了一个线程,这里就有个疑问,为什么要在一个异步请求里又调用一个线程?我们知道callbackExecutor是一个线程调度器,那他内部到底实现的是什么? 默认callbackExecutor的创建在Retrofit的初始化中,callbackExecutor = platform.defaultCallbackExecutor();

static final class Android extends Platform {

    @Override
    public Executor defaultCallbackExecutor() {
      return new MainThreadExecutor();
    }

    static final class MainThreadExecutor implements Executor {
      private final Handler handler = new Handler(Looper.getMainLooper());

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

platform是一个Android平台,defaultCallbackExecutor 内部其实调用的是 new MainThreadExecutor() ,很清楚的看到, handler.post(r) 内部使用Handler将响应抛到了主线程。

这就是Retrofit将子线程切换到主线程的核心所在。

问3:Retrofit为什么要用动态代理?

参考:

深入简出源码解析Retrofit2 - 掘金

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值