菜鸟一枚,望多批评指导(完善ing)
OKHttp源码地址:https://github.com/square/okhttp
OKHttp官方文档地址:https://github.com/square/okhttp/wiki
http://square.github.io/okhttp/
OKHttp使用
推荐使用hyman大神的OKHttpManager
http://blog.youkuaiyun.com/lmj623565791/article/details/47911083
示例:
OkHttpClient client = new OkHttpClient();
//同步网络请求
Request request_1 = new Request.Builder().url(url_1).build();
//实例化Call调用excute
Response response_1 = client.newCall(request_1).execute();
//异步网络请求
Request request_2 = new Request.Builder().url(url_2).build();
//实例化Call调用enqueue
client.newCall(request_2).enqueue(new Callback() {
@Override public void onFailure(Request request, Throwable throwable) {
...
}
@Override public void onResponse(Response response) throws IOException {
...
}
});
OKHttp网络请求流程
主要流程
->OKHttpClient①
->Call②
->HttpEngine③
->Connection④
->Transport(SDPYTransport&HttpTransport) ⑤
->HttpConnection⑥
->Sink&Source⑦
① OKHttpClient
面门类,可以通过它来调用OKHttp提供的功能且进行基本配置,内部类Internal在静态方法块里实例化
② Call
调用execute或者enqueue可进行同步或者异步请求,
getResponseWithInterceptorChain进行拦截器链拦截后再进行getResponse获取网络响应
③ HttpEngine
调用sendRequest()用于请求网络。
调用readResponse()用于获取网络响应结果。
sendRequest()判断当前请求是否已有缓存,有则获取缓存cahceResponse结果,无则继续发起网络请求(协议头输出)
readResponse()根据需要写出请求体(Body)后readNetworkResponse(),从
readNetWorkResponse获取网络请求结果
senRequest()方法里的conntect()内判断是否创建新Connection,后进行 Connection的connectAndSetOwner ()方法
④ Connection
调用connectAndSetOwner()创建socket且socket.connect
connectAndSetOwner根据请求头创建对应的socket,https调用createTLS创建SSLSocket,而其余调用createClearText创建Socket
此处根据不同Platform平台调用相对应的方法和处理方式
⑤ Transport
根据connection的类型(SpdyConnection是否为空)创建SdpyTransport还是HttpTransport
⑥ HttpConnection
调用writeRequest()请求网络
调用writeRequestbody()请求体(body)输出,
readResponse()获取网络响应结果(分析非Spdy协议请求)
⑦ Sink&Source
Sink流写出接口
Source流写入接口
关键的代码
this.source = Okio.buffer(Okio.source(socket));
this.sink = Okio.buffer(Okio.sink(socket));
此处使用装饰模式,将Sink装饰为RealBufferSink,将Source装饰为RealBufferSource
Okio.sink(socket)用于socket.getOutputStream()进行流写出,Okio.source(socket)用于socket.getInputStream()流读取。
OKHttp同步&异步请求
OKHttp的同步请求是调用Call.execute(),而异步是Call.enqueue()
Call.execute()将当前执行的Call放入到Dispatcher的executeCalls的deque队列中,后进行
getResponseWithInterceptorChain即拦截器链拦截返回结果
而Call.enqueue() 如果当前的线程总运行数量超过maxRequsets且当前所有运行的线程的Host超过maxRequsetsPerHosts则放入Dispatcher的readyCalls的deque队列中,否则则添加到runningCalls的deque队列中,且线程池运行该Call