Retrofit面试问题

介绍下Retrofit框架,Retrofit为什么要包装okhttp呢?

  • Retrofit 是一个类型安全的HTTP客户端,用于Android和Java应用。它允许你通过定义接口来描述HTTP请求,包括URL、请求方法(GET, POST等)、请求头以及请求体等内容。
  • Retrofit 包装了 OkHttp 主要是为了提供更高级别的抽象,简化网络请求的配置与执行。OkHttp 是一个高效的HTTP客户端,而 Retrofit 在其基础上提供了对REST API更加友好的支持,如动态代理、注解配置请求、数据转换等。

Retrofit主要实现机制?Retrofit的作用、原理

  • Retrofit 的核心是使用动态代理来创建接口的实现类,将HTTP请求的方法调用转化为实际的网络请求。它的作用是让开发者以一种声明式的方式来定义网络请求,并且可以很容易地进行扩展和修改。

底层是如何用 OkHttp 请求的?

  • 在底层,Retrofit 使用 OkHttp 发送网络请求。当你构建了一个 Retrofit 实例时,你可以为其指定一个 OkHttpClient 对象,这样所有由该实例发起的网络请求都会使用这个OkHttpClient。

整个请求流程是怎样的?

  1. 定义服务接口
  2. 创建Retrofit实例
  3. 生成接口的实现对象
  4. 调用对应的方法,触发网络请求
  5. 接收响应并转换为对应的Java对象

Converter 的转换过程,怎么通过 Gson 转成对应的数据模型的?

  • Retrofit 支持多种Converter库,比如Gson、Jackson等。当收到服务器响应后,Retrofit会根据你配置的Converter工厂将响应体解析成Java对象。

Retrofit如何指定一个完整的url进行请求

  • 可以通过在请求方法的注解中直接写入完整的URL来进行请求,例如@GET("https://api.example.com/data").

Retrofit返回的是什么数据类型

  • Retrofit 可以返回Call、Observable或CompletableFuture等异步结果类型,T是你希望从服务器获取的数据类型。

Retrofit怎么实现多线程

  • Retrofit 默认不处理多线程问题,但你可以通过OkHttp的dispatcher配置线程池,或者结合RxJava等异步框架来实现并发请求。

Okhttp和Retrofit设计模式上有什么异同?分别使用了什么?说一下大概原理。

  • OkHttp 主要采用了Builder模式、Factory模式。
  • Retrofit 则除了上述两种模式外,还大量使用了Proxy模式(动态代理)。

讲讲Retrofit的动态代理过程、好处

  • Retrofit利用Java的动态代理特性,在运行时为你的API接口生成实现类。这样做的好处是可以减少样板代码,提高开发效率。

Retrofit如何跨线程 Retrofit的常用配置有哪些?

  • Retrofit 本身并不直接负责线程管理和跨线程操作,但可以通过其灵活的适配器机制和第三方库(如RxJava)来实现跨线程的任务处理。
  1. 使用CallAdapter进行异步调用:Retrofit允许你定义自己的CallAdapter,通过这个适配器可以将请求的结果转换成你想要的类型。例如,默认情况下Retrofit支持Call<T>类型的返回值用于同步或基于回调的异步请求。对于更复杂的异步处理,你可以集成像RxJava这样的库,它提供了强大的操作符来处理异步数据流,并且能够方便地在不同的线程之间切换。

  2. RxJava与Schedulers:当你结合RxJava使用Retrofit时,可以利用RxJava的Schedulers来指定任务应该在哪个线程执行以及结果应该在哪一个线程被观察。例如,你可以使用subscribeOn(Schedulers.io())来指定网络请求发生在IO线程,而使用observeOn(AndroidSchedulers.mainThread())来确保结果在Android主线程被处理。

  3. OkHttp的Dispatcher:虽然这不是直接关于跨线程的方法,但是了解OkHttp的Dispatcher也很重要。Retrofit底层依赖于OkHttp发送HTTP请求,而OkHttp通过Dispatcher管理并发请求,默认情况下它会限制同时运行的请求数量并管理这些请求所在线程池。这意味着即使你不手动管理线程,OkHttp也会为你有效地处理并发请求。

  4. 自定义Executor:在创建Retrofit实例时,你可以设置一个自定义的Executor,这可以用来控制回调方法(如成功或失败回调)执行所在的线程。这对于希望对回调线程有更多控制的应用来说非常有用。

总结来说,Retrofit通过与RxJava等库的结合,以及OkHttp的调度能力,实现了灵活的跨线程操作。这种方式使得开发者可以根据应用的具体需求,轻松地在不同线程间调度网络请求和响应处理。

  • 包括设置BaseUrl、ConverterFactory、CallAdapterFactory、OkHttpClient等。

Retrofit⽹络请求层⽤的什么?

  • Retrofit 网络请求层基于OkHttp。

Retrofit中使⽤了哪些设计模式?

  • 包含但不限于Builder模式、Proxy模式、Factory模式等。

Retrofit在OkHttp上做了哪些封装?动态代理和静态代理的区别,是怎么实现的?

  • Retrofit 封装了OkHttp,使其更易于配置和使用,尤其是在处理REST API方面。
  • 动态代理是在运行时创建代理对象,而静态代理需要预先定义代理类。Retrofit使用的是前者,因为它更灵活。

你从这个Retrofit中学到什么有价值的或者说可借鉴的设计思想?

  • 模块化设计、高内聚低耦合、依赖倒置原则等。

Android开发Repository层如何拿到Retrofit返回的数据?

  • 可以通过定义Repository层的服务接口,然后注入Retrofit生成的API服务来获取数据。

Retrofit也用apt去做是否可行?为什么不用apt而用动态代理?

  • Retrofit 早期版本确实使用了 APT (Annotation Processing Tool),但现在更多是利用Java的动态代理功能。

怎么更好的处理Retrofit工具类中将拦截到401状态码?

  • 可以通过自定义Interceptor拦截响应,检查状态码是否为401,然后采取相应的措施,如刷新token等。