OkHttp是什么,为什么要用OkHttp
- 支持允许所有访问同一主机的请求共享一个socket
- 内置连接池,支持连接复用,减少延迟
- 透明GZIP缩小了下载大小
- 响应缓存完全避免了重复请求的网络
- 请请求失败时自动重试主机的其他ip,自动重定向
- 支持同步阻塞调用和带回调的异步调用
OkHttp3 的原理
okhttp3的底层是socket,它是通过Platform的Class.forName反射获取当前的Runtime使用socket库。Socket的使用是创建socket对象,然后连接到目标网络,封装在connection接口中,由RealConnection类实现,再通过stream接口来实现输入输出流操作。根据不同的网络协议,分为Http1xStream和Http2xStream两个类来实现。由于创建网络连接的时间比较久,如果是http的话,需要进行三次握手,而请求经常是频繁的碎片化,为了提高网络连接的效率,Okhttp3实现了网络连接复用。
Okhttp3运用到的设计模式
-
单例模式:
okhttpclient用单列模式创建,每个okhttpclient对象都管理自己独有的线程池和连接池。
-
Builder模式:
okhttpclient属性太多,使用的组合需求多样化,所以okhttp使用构建者模式。
-
工厂模式:
Call接口提供了内部接口Factory,我们在创建对象时不会对使用者暴露创建逻辑,并且通过使用一个共同的接口来指向新创建的对象。
- 责任链模式:
在okhttp拦截器模块执行过程用到,OKhtt3拦截器中内置了5个默认的拦截器,用于,重试,请求对象转换,缓存,连接和网络读写。 - 策略模式:
CacheInterceptor实现数据的选择策略,来自网络还是来自本地。
OkHttp3使用方式
创建okhttpclient分两种,
-
第一种:new OkHttpClient(),这种方式okhttp做了很多工作。属性获得了默认值。
-
第二种:new OkhttpClient.Builder()….builder(),属性获得了默认值,我们可以利用构建者模式单独的设置每一个属性的值。
我们在创建okhttpclient的时候,最好采用单例模式,因为每一个okhttpclient都有自己单独的连接池和线程池,复用连接池和线程池能减少延迟,节省内存。
接口回调:
我们在使用execute和enqueue这两个方法,传入okhttp中的RealCall类,再调用RealCall的getResponseWithInterceptorChain()方法,从拦截器链中获取返回结果。拦截器链依次通过重定向拦截器,桥接拦截器,缓存拦截器,连接拦截器,网络拦截器对请求依次解决,建立连接后,获取返回数据,再经过上面的拦截器依次解决后,最后将返回给调用方。
Retrofit
-
什么是Retrofit?
Retrofit就是一个封装了Http请求的框架,底层的网络请求都是使用的Okhttp,本身只是简化了用户网络请求的参数配置等,还能与Rxjava相结合,使用起来更加简便。
-
原理
通过java接口以及注解来描述网络请求,并用动态代理的方式,在调用接口方法前后注入自己的方法,在调用前通过接口方法和注解生成网络请求的request,调用后通过client调用响应的网络框架,默认的是okhttp,去发起网络请求,并将返回的response通过convertFactorty转换成相应的数据model,最后通过calladapter转换成其他数据方式(如rxjava,Observable)。
框架中使用动态代理,代理对象拦截真实对象的方法调用,在真实对象调用前或调用后实现自己的逻辑调用Retrofit.create方法。
通过建造者模式构建一个Retrofit实例,配置baseUrl,callAdapterFactory(将代理返回的Call对象转化为其他,比如Rxjava的Observer),converterFactory(结果的转化器,将请求的结果转化为特定的对象时使用,比如GsonConverterFactory)。
通过Retrofit对象的create(Class service)方法返回一个Service的动态代理对象,在调用service的方法的时候,就是调用动态代理的invoke方法。
调用代理的invoke方法的时候,会将method进行解析,解析我们在接口里面配置的各种注解,最后构造成ServiceMethod对象,并将结果缓存起来,下次再次调用就不用解析了。ServiceMethod对象可以生成Request对象,所以将ServiceMethod对象注入到OkHttpCall,然后通过callAdapter转化为用户希望得到的返回对象,默认是直接返回Call对象。
返回Call对象之后,我们再调用execute或者enqueue方法,前者是同步请求,后者是异步请求,再方法里面会调用Okhttp的网络请求方法。
Rxjava
-
RxJava是什么
官网是上这样解释的,一个在java vm上使用可观测的序列来组成异步的,基于事件的程序的库。
-
Rxjava主要作用
Rxjava主要作用就是用来处理异步,当你的业务需要访问数据库,访问网络,或者任何耗时的操作,都可以借助Rxjava来实现。
-
处理异步任务可以用Handler,AsyncTask等来实现,我们为什么还要用Rxjava?
- 采用链式调用,代码简洁优雅有美感,并且可读性增强。
- rxjava中采用观察者模式。模块之间划定了清晰的界限,降低了模块间的耦合性,提高了代码的可维护性和重用性。
- rxjava中提供了强大的操作符。
什么是背压
- TCP 和UDP的区别
| UDP | TCP | |
|---|---|---|
| 是否连接 | 无连接 | 面向连接 |
| 是否可靠 | 不可靠传输,不使用流量控制和拥塞控制 | 可靠传输,采用流量控制和拥塞控制 |
| 连接对象个数 | 一对一、一对多、多对多,互相通信 | 一对一通信 |
| 传输方式 | 面向报文 | 面向字节流 |
| 首部开销 | 首部开销小,仅8字节 | 首部最小20字节,最大60字节 |
| 适用场景 | 适用于实时应用(IP电话、视频会议、直播等) | 适用于要求可靠的应用(文件传输) |
- 总结:
TCP向上层提供面向连接的可靠服务 ,UDP向上层提供无连接不可靠服务。
虽然 UDP 并没有 TCP 传输来的准确,但是也能在很多实时性要求高的地方有所作为
对数据准确性要求高,速度可以相对较慢的,可以选用TCP










网友评论