http 1.0 和http1.1的区别
http 1.0 如果一个请求发到服务器 每次的传输 都会有 三次握手 四次挥手
客户端建立连接 发送请求到服务器 服务器发送消息给客户端 连接成功
客户端收到服务器发过来的消息 客户端发送数据包给服务器
互相通知 两次断开 最后一次服务器断开发送给客户端
1.1 可以进行长链接 可以不停的交互 直到不需要连接 进行四次挥手 断开连接
htpp
第一行: 请求行
请求行下面的: 请求的属性集 Header请求头 以及请求参数
请求状态码
请求时间 字符类型
请求返回的具体内容
1.为什么选择okHttp 而不是其他框架
OKHttp基于socket通讯,它更倾向于底层,会对http协议进行完全的封装
第一点:谷歌官方在6.0以后在android sdk已经移除了httpClient,加入我们okHttp.
第二点:okHttp支持SPDY(是谷歌开发的基于TCP的应用层协议,用于最小化网络延迟,提升网络速度,优化用户的网络使用体验. SPDY并不是一种替代http的协议,只是对http的一种增强.)允许连接在一主机的所有请求分享一个socket.如果SPDY不可用.会使用连接池来减少请求延迟.利用响应缓存来避免重复的网络请求.即便是网络出现问题时,okhttp依然起作用.它将从常见的链接问题当中回复.如果你的服务器有多个IP地址,当地一个失败时,okhttp会自动尝试连接其他的地址.这对于IPV4和IPV6以及寄宿在多个数据中心的服务而言,是非常有必要的,所以okhttp的稳定性可以说是非常棒的.
2.为什么retrofit能请求为什么还要+okhttp
因为retrofit只是一个网络框架的封装,他不负责请求,内部源码请求还是okhttp。他是把接口方法动态代理转换成ok能读懂的请求的,你要是想配置拦截器,超时等,你还得引入okhttp自己配置啊
OKHttp 流程详解
1.new OKhttpClient() 初始化一个OKhttpClient
2.初始化一个Request.Builder 这个里面 可以.url .addHeader(name,value)
.build();等一些请求参数 设置请求类型 默认是GET请求类型
3.创建一个Call call=okhttpClient.newCall(request)
call.execute(new Callback) 同步请求
Call.enqueue(new Callback) 异步请求
在new Call中 会返回一个RealCall.newRealCall的方法 这里进行相关操作
Call call= return RealCall.newRealCall(this, request, false /* for web socket */);
在执行call.execute或者call.enqueue的时候跳转到realcall
//分发同步或异步 在这个exexuted()中吧穿进去的RealCall添加进一个runingSyncCall队列中去
然后这里这个retrun getResponseWithInterceptorChain(); 这句代码执行之后返回了一个 Response 就是我们发送数据,服务器给我们的相应数据 在这个getResponseWithInterceptorChain中进行了一些拦截器的操作
这样同步请求会直接等待服务器返回的一个Response 我们就回对这个Response进行处理
异步请求
enqueue()异步请求也是在RealCall中实现
在RealCall中 有个pulic void enequeue(Callback responeCallback)方法
这里会用client.dispatcher.enqueue(new AsynCall(respnseCallback))
client.dispatcher().enqueue这个方法也是分发器中实现的
在分发器中 吧穿进去的new AsyncCall(respnseCallback)子线程添加到了一个队列 readyAsynsCalls中去 然后执行promoteAndExecute()方法
promoteAndExecute();这个方法中asyncCall.executeOn(executorService());
进行了一个线程池的创建操作
client.dispatcher().enqueue(new AsyncCall(responseCallback));
然后回到之前 AsyncCall() 这个继承了 NamedRunnable这个类
这个类是个抽象类,里面有写到 extctue抽象方法 那么AsyncCall这里面就会执行 extctue
这里就是在RealCall中的AsyncCall类里面重写的void execute方法
@Override protected void execute() {
在这个方法里面我们得到了发起请求后的Response
Response response = getResponseWithInterceptorChain();
signalledCallback =true;
responseCallback.onResponse(RealCall.this, response)
然后在请求外面的CallBack里面onResponse 进行相应的操作
总结:
1)同步和异步都是通过Dispatch这个分发器来分发的。
2)异步操作比同步操作多了创建线程池的操作,开启了子线程。
3)同步和异步最后都走到了getResponseWithInterceptorChain这个方法。
OKhttp拦截器的使用
拦截器分为内部拦截器 和外部拦截器
内部拦截器有5个
外部拦截器就是自己定义的拦截器
还可以分为应用拦截器和网络拦截器 这两个拦截器都需要实现intercept接口
应用拦截器:关注的是发起请求,不能拦截发起请求到请求成功后返回数据的中间的这段时间 也就是说 在发起请求之前 这个拦截器是生效的 很简单的一个例子 添加一个TokenHeaderIntercpter 定义个token 吧这个token添加到 builder中的header里面去
OkHttpClient.Builder okHttpClient2 = new OkHttpClient().newBuilder();
okHttpClient2.addInterceptor(new TokenHeaderInterceptor());
public class TokenHeaderInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
// get token
String token = "123456";
Request originalRequest = chain.request();
// get new request, add request header
Request updateRequest = originalRequest.newBuilder()
.header("token", token)
.build();
return chain.proceed(updateRequest);
}
}
网络拦截器:是发起请求和请求后获取的数据中间这样一个过程 这这个过程中起到作用
前者是.addIntercpter 它是addNetWorkIntercepter 从名字就能看出来 是不一样的拦截器
应用拦截器和网络拦截器区别在于 网络拦截器可以重定向
在getResponseWithIntercepterChain方法里面 可以看到有一个list
会吧okhttpclient中所有的intercepttian添加到这个list里面去可以看到在添加完自定义intercept之后 还会添加五个拦截器
RetryAndFollowUpInterceptor //重试和失败重定向拦截器,会创建StreamAllocation对象,用来传递给后面的拦截器
BridgeInterceptor 桥接和适配拦截器
CacheInterceptor 缓存拦截器
BridgeInterceptor和CacheInterceptor用于补充用户创建请求中缺少的一些必须请求头,和处理缓存功能
ConnectInterceptor 连接拦截器,建立可用的连接,是CallServerIntercpter的基础
CallServerInterceptor 负责将我们的请求写进网络流中,并且我们会从网络Io流当中读取服务器返回给我们的客户端的数据
RetryAndFollowUpIntercepto
主要执行工作
1.创建一个StreamAllocation对象
2.调用RealIntercepterChainrealChain.proceed(requesr,streamAllocation,null.null) 通过chain对象调用下一个拦截器 BirgeIntercepter
3.从下一个拦截器接受传递过来的Response 根据异常和相应结果判断是否需要重连
4.处理完成之后将Response返回给上一个拦截器 就是getResponseWithIntercepterChian这个拦截器
BirgeIntercepter拦截器
这个拦截器 负责设置内容长度,编码方式,设置gzip压缩,添加请求头,cookie等相关功能
桥接拦截器是链接客户端和网络代码的桥梁, 这个拦截器会根据用户请求创建真正的网络请求 NetWork Request
主要功能
1、负责将用户构建的一个Request请求转换成一个能够进行网络访问的请求
2. 将这个符合网络请求的Response转化为用户可以使用的Response
CacheIntercepter拦截器
缓存拦截器, 为什么要使用缓存?
一个优点就是让客户端下一次进行网络请求的时候能够节省更多的时间,更快的展示数据
如果有网络请求数据缓存, 客户端在没有网络的情况下,会直接返回缓存结果,避免很多尴尬现象
当CacheIntercept拦截到请求之后会调用cache类中的put方法 cache类 实现了internalCache接口,此接口定义了真删改查等方法
Http的缓存的工作是通过CacheIntercept拦截器完成的
如果当前未使用网络,并且网络不可用的时候,通过构建者模式会串讲一个Response相应抛出504错误,告诉客户端 网络不可用
如果有缓存,但是不能请求网 会直接返回缓存结果
这是在进行网络请求之前所做的事情, 当网络请求完成,得到下一个拦截器返回的Response之后根据Response的响应码是否是HTTP_NOT_MODIFIED=304(未改变) 那就会缓存中读取数据
这个拦截器负责打开服务之间的TCP连接,正式开启okhttp的网络请求
ConnectIntercepter执行完请求之后接着做的就是读取服务器相应的数据,构建resonse.builder对象
主要做了两个工作
1.调用HttpCodec的readResponseHeaders方法读取服务器相应数据,构建Response.Builderd对象
2.通过ResponseBuilder对象来创建Response对象并返回,主要是调动Http1Codec对象的openResponseBody方法,此方法讲Scoket的输入流inputStream对象交给Oklo的Source对象,然后方封装成RealResponseBody作为Response的body
CallServerIntercepter拦截器
主要做了如下工作
1.获取HttpCodec对象 对Http协议的http请求进行处理
2.发送http请求数据,构建Response.Builder对象,然后构建Response并返回