• 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 - 掘金

  • 相关阅读:
    历时三个月,史上最详细的Spring注解驱动开发系列教程终于出炉了,给你全新震撼
    年产10万吨环氧树脂车间工艺设计
    这两个工具能批量PDF转图片,建议收藏使用
    【Arduino27】DHT11温湿度传感器模拟值实验
    Python---类的定义和使用语法
    【力扣hot100】刷题笔记Day22
    laravel 子查询
    企业运维实战 ELK日志分析平台 Kinaba (Kibana安装、Kinaba安全认证、Kinaba监测)
    【AutoSAR】 CP 和 AP
    【李沐深度学习笔记】线性代数实现
  • 原文地址:https://blog.csdn.net/qq_37492806/article/details/133995368