当前位置:   article > 正文

Retrofit面试题系列

retrofit面试题

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

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

问1:什么是动态代理?

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

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

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

  1. static final class ExecutorCallbackCall<T> implements Call<T> {
  2. final Executor callbackExecutor;
  3. final Call<T> delegate;
  4. ...
  5. @Override
  6. public void enqueue(final Callback<T> callback) {
  7. delegate.enqueue(
  8. new Callback<T>() {
  9. @Override
  10. public void onResponse(Call<T> call, final Response<T> response) {
  11. callbackExecutor.execute(
  12. () -> {
  13. if (delegate.isCanceled()) {
  14. // Emulate OkHttp's behavior of throwing/delivering an IOException on
  15. // cancellation.
  16. callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled"));
  17. } else {
  18. callback.onResponse(ExecutorCallbackCall.this, response);
  19. }
  20. });
  21. }
  22. @Override
  23. public void onFailure(Call<T> call, final Throwable t) {
  24. callbackExecutor.execute(() -> callback.onFailure(ExecutorCallbackCall.this, t));
  25. }
  26. });
  27. }

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

  1. static final class Android extends Platform {
  2. @Override
  3. public Executor defaultCallbackExecutor() {
  4. return new MainThreadExecutor();
  5. }
  6. static final class MainThreadExecutor implements Executor {
  7. private final Handler handler = new Handler(Looper.getMainLooper());
  8. @Override
  9. public void execute(Runnable r) {
  10. handler.post(r);
  11. }
  12. }
  13. }
  14. }

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

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

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

参考:

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/859354
推荐阅读
相关标签
  

闽ICP备14008679号