OkHttp解析
来源:互联网 发布:照片打印软件免费版 编辑:程序博客网 时间:2024/05/22 12:14
okhttp正题架构
okhttp源码解析
优点:
1支持HTTP2 ,支持统一主机服务器共享同一socket通信;提高了请求效率
2在http2的情况下通过连接池减少请求的延迟
3gzip压缩减少网络数据的流量
4响应缓存避免同一重复请求
okhttp的两种调用方式
同步直接调用RealCall的execute最终调用的是getResponseWithInterceptorChain(forWevSocket)
@Override protected void execute() { boolean signalledCallback = false; try { Response response = getResponseWithInterceptorChain(forWebSocket); if (canceled) { signalledCallback = true; responseCallback.onFailure(RealCall.this, new IOException("Canceled")); } else { signalledCallback = true; responseCallback.onResponse(RealCall.this, response); } } catch (IOException e) { if (signalledCallback) { // Do not signal the callback twice! Platform.get().log(INFO, "Callback failure for " + toLoggableString(), e); } else { responseCallback.onFailure(RealCall.this, e); } } finally { client.dispatcher().finished(this); } }而异步调用时:
enqueue中调用Dispatcher的enqueue方法
synchronized void enqueue(AsyncCall call) { if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) { runningAsyncCalls.add(call); executorService().execute(call); } else { readyAsyncCalls.add(call); } }通过ExecutorService启动线程池开启线程最终调用RealCall的execute还是会调用getResponseWithInterceptorChain(forWevSocket)方法
最终getResponseWithInterceptorChain(forWevSocket)通过一系列的Interceptors完成配置 请求
OkHttp总体架构:
大致分为
1、Interface-接口层:接收网络访问请求
2、Protocol-协议层:处理协议逻辑
3、Connection-连接层:管理网络链接,发送新的请求,接收消息响应
4、Cache-缓存层:管理本地缓存
5、I/O层--实际数据读取与实现
6、Interceptor-拦截层:拦截网络访问,插入拦截逻辑
OkHttpClient
是OkHttp框架的客户端,更确切的说是一个用户面板。用户使用OkHttp进行各种设置,发起各种网络请求都是通过OkHttpClient
完成的。每个OkHttpClient
内部都维护了属于自己的任务队列,连接池,Cache,拦截器等,所以在使用OkHttp作为网络框架时应该全局共享一个OkHttpClient
实例。
RealCall:OkHttp会为每一个请求创建一个RealCall
,每一个RealCall
内部有一个AsyncCall
(继承NameRunnable implements
Runnable所以每一个Call就是一个线程 执行其execute()方法
Dispatcher
是OkHttp的任务队列,其内部维护了一个线程池(最大限度的复用现有连接),当有接收到一个Call
时,Dispatcher
负责在线程池中找到空闲的线程并执行其execute
方法
拦截层
getResponseWithInterceptorChain方法最终调用ApplicationInterceptorChain中的proceed方法
private Response getResponseWithInterceptorChain(boolean forWebSocket) throws IOException { Interceptor.Chain chain = new ApplicationInterceptorChain(0, originalRequest, forWebSocket); return chain.proceed(originalRequest); }最终调用对应的Interceptor的intercept方法
@Override public Response proceed(Request request) throws IOException { // If there's another interceptor in the chain, call that. if (index < client.interceptors().size()) { Interceptor.Chain chain = new ApplicationInterceptorChain(index + 1, request, forWebSocket); Interceptor interceptor = client.interceptors().get(index); Response interceptedResponse = interceptor.intercept(chain); if (interceptedResponse == null) { throw new NullPointerException("application interceptor " + interceptor + " returned null"); } return interceptedResponse; } // No more interceptors. Do HTTP. return getResponse(request, forWebSocket); }
一下是各种拦截器
RetryAndFollowUpInterceptor
@Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); RealInterceptorChain realChain = (RealInterceptorChain) chain; Call call = realChain.call(); EventListener eventListener = realChain.eventListener(); streamAllocation = new StreamAllocation(client.connectionPool(), createAddress(request.url()), call, eventListener, callStackTrace); int followUpCount = 0; Response priorResponse = null; while (true) { if (canceled) { streamAllocation.release(); throw new IOException("Canceled"); } Response response; boolean releaseConnection = true; try { response = realChain.proceed(request, streamAllocation, null, null); releaseConnection = false; } catch (RouteException e) { // The attempt to connect via a route failed. The request will not have been sent. if (!recover(e.getLastConnectException(), false, request)) { throw e.getLastConnectException(); } releaseConnection = false; continue; } catch (IOException e) { // An attempt to communicate with a server failed. The request may have been sent. boolean requestSendStarted = !(e instanceof ConnectionShutdownException); if (!recover(e, requestSendStarted, request)) throw e; releaseConnection = false; continue; } finally { // We're throwing an unchecked exception. Release any resources. if (releaseConnection) { streamAllocation.streamFailed(null); streamAllocation.release(); } } // Attach the prior response if it exists. Such responses never have a body. if (priorResponse != null) { response = response.newBuilder() .priorResponse(priorResponse.newBuilder() .body(null) .build()) .build(); } Request followUp = followUpRequest(response); if (followUp == null) { if (!forWebSocket) { streamAllocation.release(); } return response; } closeQuietly(response.body()); if (++followUpCount > MAX_FOLLOW_UPS) { streamAllocation.release(); throw new ProtocolException("Too many follow-up requests: " + followUpCount); } if (followUp.body() instanceof UnrepeatableRequestBody) { streamAllocation.release(); throw new HttpRetryException("Cannot retry streamed HTTP body", response.code()); } if (!sameConnection(response, followUp.url())) { streamAllocation.release(); streamAllocation = new StreamAllocation(client.connectionPool(), createAddress(followUp.url()), call, eventListener, callStackTrace); } else if (streamAllocation.codec() != null) { throw new IllegalStateException("Closing the body of " + response + " didn't close its backing stream. Bad interceptor?"); } request = followUp; priorResponse = response; } }response = realChain.proceed(request, streamAllocation, null, null);这行代码就是执行下一个拦截器链的proceed方法。而我们知道在下一个拦截器链中又会执行下一个拦截器的intercept方法。所以整个执行链就在拦截器与拦截器链中交替执行,最终完成所有拦截器的操作。这也是OkHttp拦截器的链式执行逻辑。而一个拦截器的intercept方法所执行的逻辑大致分为三部分:
- 在发起请求前对request进行处理
- 调用下一个拦截器,获取response
- 对response进行处理,返回给上一个拦截器
几个核心的拦截器
- RetryAndFollowUpInterceptor
- BridgeInterceptor
- CacheInterceptor
- ConnectIntercetot
- CallServerInterceptor
okhttp的多路复用:
ConnectionPool
okhttp中的坑
- OKhttp解析
- OKhttp解析
- OKHTTP解析
- OkHttp解析
- okhttp解析
- OkHttp解析
- OKHttp源码解析
- OKHttp源码解析
- OKHttp源码解析
- OKHTTP解析json数据
- Android OkHttp完全解析
- OKHttp源码解析
- OkHttp解析系列-开篇
- OKHttp源码解析
- Android OkHttp完全解析
- OKHttp源码解析
- Android OkHttp完全解析
- Android OkHttp解析
- 第1章 Git入门
- SpringMVC处理异步请求
- python3.4 字符串转16进制
- Spring Cache抽象详解
- 怎么做零食代理?经销商要掌握经营技巧
- OkHttp解析
- JSP, Servlet常见面试题详解
- K-最近邻法(KNN)简介
- json和jsonP
- java枚举类
- Spring整合MockMvc单元测试,Java配置
- windows下安装pywin32报错:close failed in file object destructor:sys.excepthook is missing lost sys.stderr
- 区块链技术如何实现转账山寨币交易验证系统的开发
- 基于MT4平台实现二元交易的思路