• 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 implements Call {
    2. final Executor callbackExecutor;
    3. final Call delegate;
    4. ...
    5. @Override
    6. public void enqueue(final Callback callback) {
    7. delegate.enqueue(
    8. new Callback() {
    9. @Override
    10. public void onResponse(Call call, final Response 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 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 - 掘金

  • 相关阅读:
    【免费】两阶段鲁棒优化matlab实现——C&CG和benders
    3.Android应用资源:处理配置变更
    牛客刷题<八>使用generate...for语句简化语句
    Activiti7报错:org.springframework.security.core.userdetails.UserDetailsService
    前端技术面试核心问题(持续更新)
    PAT A1013 Battle Over Cities分数 25(连通块数量,割点是针对连通块的,不是整个图)
    Java要将字符串转换为Map
    极客星球 | 业务监控及告警系统体系化建设之路
    前台自动化测试:基于敏捷测试驱动开发(TDD)的自动化测试原理
    OB_GINS_day3
  • 原文地址:https://blog.csdn.net/qq_37492806/article/details/133995368