android 网络库
网络库重点:
- 稳定
- 高效,可以复用连接
- 有缓存,不用重复请求
okhttp
毋庸置疑,使用 okhttp 做为网络框架。
okhttp 已经稳定使用很长时间,应用很广泛。
okhttp 多路复用,有连接池。初步来看时根据 host 等等进行复用。连接池默认是5个,5分钟
- 提供了 okio 进行读写。Buffer 使用双向链表 segment(segment 还有 compact 和 flit 优化,以及 segmentpool 来进行维护) 来进行存储数据,输入输出经过 buffer 达到低的CPU和内存消耗。
- okhttp 是依靠先判断 host 在判断是否归为一个 route ,且支持 http2 多路复用。
okhttp 自己有缓存策略,可以 new Cache 指定缓存目录和大小,内部会使用 LRU 策略清理。也可以自己 Request 设置 CasheControl ,推荐有 FORCE_NETWORK 和FORCE_CACHE,不符合要求可以自己设置builder。
- 服务器支持缓存,即服务器在 response 头部有 Cache-Control, okhttp 会处理对应情况。
- 服务器不支持缓存,想要支持就要在 NetworkInterceptor 里面处理 response,remove Pragma ,添加 Cache-Control。
retrofit
对 okhttp 进行了封装。
Retrofit 是一个 restful 的 HTTP 网络请求框架的封装。
网络请求的工作本质上是 OkHttp 完成,而 Retrofit 仅负责 网络请求接口的封装
App应用程序通过 Retrofit 请求网络,实际上是使用 Retrofit 接口层封装请求参数、Header、Url 等信息,之后由 OkHttp 完成后续的请求操作
在服务端返回数据之后,OkHttp 将原始的结果交给 Retrofit,Retrofit根据用户的需求对结果进行解析
相对其他开源库而言代码简洁使用更加方便.
感想
阅读这2个库发现一些很有意思的事情
- 因为 Cache 类和 CacheInterceptor 不在一个目录下,CacheInterceptor 需要持有 Cache 实例。一般做法是 Cache public ,对应方法也要 public。但是 okhttp 并没有这么做。它定义了一个接口 InternalCache。Cache 类内部 持有实现了 InternalCache 实例。CacheInterceptor 类再由 okhttp client 构造里面传递进来 cache 里的 InternalCache示例。从而实现了 Cache 类方法不 public 另外目录也可以调用,且调用由接口来约束。在4.X版本 okhttp 用 kotlin 实现,因为 kotlin 可以控制包内访问,所以删除了 InternalCache 接口类。
这种场景平时其实平时很容易碰到,为了项目易维护,要分目录来进行划分,但是 java 因为语言特性,一旦外界想要访问必须要 public 。结果导致很多不想 public 的方法因此暴露或者导致无法放在不同目录下。okhttp 这种思路虽然略显 繁琐,但符合开发原则。值得推荐学习。 - 定义了一个 Internal 抽象类,内部持有自身实例 public static Internal instance,由 OkHttpClient 主对外类来实现并赋值。从而来打通 internal 目录下和外界的调用。okhttp 做的很好的点在于将面向对象特性发挥的很好。类职责较单一,但类实例传递很频繁。往往一个类层层传递到深处仍在正常使用。这对类实例稳定性其实由很高的要求。
- retrofit 不涉及具体网络请求,对请求和返回值等接口做了封装。要是我们自己简单使用的话,实际上不需要retrofit,统一封装一个 request、response 就可以。但是从程序设计的角度,考虑以后扩展的话,就不得不考虑 request 多样性、reponse 多样性和是否可以转换,具体请求是否可以方便替换等等。retrofit 做到了这些,同时还采用了注解的方式,来简化了很多代码,从易用性和可扩展性上实现了平衡,请求用注解,后续很多都采用 adapter,factory 来实现可扩展。从测试方面,retrofit 对外提供了 mock 库,可以自己定义 response 返回,当然,因为它是基于 okhttp 的,用拦截器也能实现。对内单元测试覆盖较全,使用 mockwebserver 模拟请求。