在讲OKhttp之前我们先说一下http的的出现及发展
HTTP协议结构
http的组成是请求头,请求体,响应头,响应体。
请求头:本次请求的客户端;本次请求所使用的cookie;本次请求需要返回的数据类型;本次请求是否采用数据压缩等等设置。
请求体:指定本次请求所使用的方法是get/post;主要用来携带本次请求的参数。
响应头:服务器的标识;状态码200/300/404/500等;内容编码;服务器返回给客户端的cookie。
响应体:就是我们本次请求所返回的数据
HTTP协议工作的一个流程
1、首先客户机与服务器需要建立连接
2、建立连接后,客户机发送一个请求给服务器
3、服务器接到请求后,给予相应的响应信息
4、客户端接收服务器所返回的信息,连接断开
HTTP协议的优势
简单快速;灵活;无连接;无状态
SPDY介绍
SPDY是兼容性协议
多路复用请求
对请求划分优先级
压缩请求头
HTTP2.0是基于SPDY,IETF定制的新一代HTTP协议
更安全的SSL
终于来到了我们的重点OKhttp,为我们android客户端支持HTTP2.0提供了途径。
那么OKhttp有哪些优势呢?
1)OKhttp如果支持SPDY,HTTP2.0共享同一个socket来处理同一个服务器的所有请求
2)如果SPDY不可用,则通过连接池来减少请求延时
3)无缝的支持GZIP来减少数据流量
4)缓存响应数据来减少重复的网络数据
5)可以从很多常用的连接问题中自动恢复。
接下来我们看一张OKhttp框架的基本原理图
对这张图片讲解,请求request----》到达了分发器-----》分发器就会传递到HttpEngine,这个HttpEngine就是真正干活的人,他会看这次缓存有没有缓存,如果有从缓存里面拿到信息,如果没有它就会到连接池中,从连接池中创建一个connnection连接,通过connnection发我们真正的请求,请求到以后通过路由和Platform找到一个合适的平台,这时候通过Server、socket获得Data。
下面这张是执行流程图:
大概流程是这样的:
1.用构造者模式去创建一个请求(Request)
okhttp普遍使用构建者模式开发
Request.Builder
2.添加到分发器中(Dispatcher)
3.由分发器分发到httpEngine,如果这个请求在之前有缓存过,那么直接返回缓存的Response,否者创建连接。
(HttpEngine首先调用nextConnection(),获取不到Connection 才会调用createNextConnection())
4.从连接池中获得一个连接,进行网络请求(...)
OKhttp支持各种版本的协议并且具有下面两种特性。
多路复用机制:HttpEngine(Http引擎)每次请求数据时,都会先调用nextConnection(),如果返回一个连接对象,则就调用sendRequest()发送一个请求。如果nextConnection()返回为null,就会调用createNextConnection()创建一个连接,然后去发送请求。
重连机制:通过一个while的循环,判断条件是当前状态是否连接,如果没有连接,就会调用getResquese()发送请求,紧接着HttpEngine调用recover(),进行重连操作,直到当前连接状态为已连接,结束循环。
OKhttp源码解析:
首先看一下Route类,路由类,它主要是封装了Address,所有要请求的端口号,服务器的ip地址等等。最后在建立connnection的时候,从我们的Route类中获取相对应的数据;ResponseBody响应体类,返回的所有数据最初都是字节码。操作的就是这个字节数组,把它转化成String类型或者图片类型,每一个call都是我们最终要实行的一个接口;分发器类,里面有一个线程池,包括两种异步的,一种同步的方法;HttpEngine是真正的发送请求的,他是核心类,真正的发送请求,响应处理,重连机制等,核心方法SendRequest()各个类之间的配合通过OKhttpClient。
简单的介绍了一些OKhttp的源码类,我们通过实际代码进行一些简单的演示
通过OKhttp进行get请求:
/**
* 需要注意的是此时还在费UI线程中要想更新UI需要使用handler或者runOnUiThread
*/
//发送一个get请求
public void getRequest() {
//构建请求体
final Request request = new Request.Builder().url("https://hao.360.cn/").build();
OkHttpClient client = new OkHttpClient();
//通过request构造了一个任务类call
Call call = client.newCall(request);
//把call调度起来,call的回调方法来响应我们的请求
call.enqueue(new Callback() {
@Override
public void onFailure(Request request, IOException e) {
}
@Override
public void onResponse(Response response) throws IOException {
final String a = response.body().toString();
runOnUiThread(new Runnable() {
@Override
public void run() {
//可以在这里面更新ui
}
});
}
});
}
通过OKhttp进行post请求:
/**