OkHttp的实现原理(二)之异步
来源:互联网 发布:兄弟连php怎么样 编辑:程序博客网 时间:2024/06/07 20:42
上一篇我分析了OkHttp采用同步请求的实现原理,这一篇我将继续分析它的第二种请求方式——异步请求,由于这是基于上一篇文章的内容之上的,所以在看这篇文章之前请先浏览上一篇文章http://blog.csdn.net/kbqf24/article/details/56839535。
所谓异步,就是我们不需要坐着等待它出结果,当它有了结果后会回调相应的方法。
让我们来看看OKHttp的异步请求是如何实现的:
public void enqueue(Callback responseCallback) { this.enqueue(responseCallback, false); }
我们要传一个Callback接口对象进去,
void enqueue(Callback responseCallback, boolean forWebSocket) { synchronized(this) { if(this.executed) { throw new IllegalStateException("Already Executed"); } this.executed = true; } this.client.getDispatcher().enqueue(new Call.AsyncCall(responseCallback, forWebSocket, null)); }
首先还是要获得一个分发器,这点跟同步请求是一模一样的,接着往下看
synchronized void enqueue(AsyncCall call) { if(this.runningCalls.size() < this.maxRequests && this.runningCallsForHost(call) < this.maxRequestsPerHost) { this.runningCalls.add(call); this.getExecutorService().execute(call); } else { this.readyCalls.add(call); } }
原来进行异步请求是有门槛限制的,它要求总的异步请求的数量小于maxRequests =64,并且对于一个主机来说最多同时发出5个请求,如果没有满足这个条件,那么就将这个call对象加入到readyCalls数组中以备日后使用,这个数组相当于是一个缓冲数组,如果满足了这个条件,那么就将AsyncCall这个对象添加到runningCalls数组当中,并且使用线程池来执行这个任务,那么这个AsyncCall到底是什么了?它是Call的一个内部类并且实现了Runnable接口,那么走 this.getExecutorService().execute(call);这个方法当然就是要去执行call里面的run()方法啊,我们来看看这个方法:
public final void run() { String oldName = Thread.currentThread().getName(); Thread.currentThread().setName(this.name); try { this.execute(); } finally { Thread.currentThread().setName(oldName); } }
这个方法会去执行execute(),并且会在执行期间给每个任务所在的线程取不同的名字。
protected void execute() { boolean signalledCallback = false; try { Response e = Call.this.getResponseWithInterceptorChain(this.forWebSocket); if(Call.this.canceled) { signalledCallback = true; this.responseCallback.onFailure(Call.this.originalRequest, new IOException("Canceled")); } else { signalledCallback = true; this.responseCallback.onResponse(e); } } catch (IOException var7) { if(signalledCallback) { Internal.logger.log(Level.INFO, "Callback failure for " + Call.this.toLoggableString(), var7); } else { Request request = Call.this.engine == null?Call.this.originalRequest:Call.this.engine.getRequest(); this.responseCallback.onFailure(request, var7); } } finally { Call.this.client.getDispatcher().finished(this); } }
Response e = Call.this.getResponseWithInterceptorChain(this.forWebSocket);
这个方法是不是也很熟悉啊,跟同步获取数据的方法是一摸一样的,一个方法在上一篇文章中详细说明了的,这里就不再展开来说了,然后再判断这个任务是否被cancel掉了,如果是,那么就会调用我们传入的Callback接口对象的onFailure()方法,如果没有被取消,那么就会回调该接口中的onResponse(response)方法。
那么异步请求的代码我们也就分析完了,跟同步请求其实区别并不大,我们来分析一下他们的区别,
1. 同步:将Call对象之间放入分发器Dispatcher中
异步:将AsyncCall对象放入分发器Dispatcher中,
2. 同步方法不会自动给你开线程去调用getResponseWithInterceptorChain(this.forWebSocket)获取数据,所以你必须自己开启线程去执行。
异步方法OkHttp会使用内部的线程池中的线程去执行获取数据(getResponseWithInterceptorChain(this.forWebSocket))的耗时操作,所以你可以在主线程中使用异步请求。
3. 同步方法拿到返回的结果后直接返回,而异步请求获取到结果后并不直接返回,而是将结果作为参数回调接口的方法去使用的。
- OkHttp的实现原理(二)之异步
- OkHttp的实现原理(一)之同步
- (4.2.36.2)HTTP之OkHttp(二): Okhttp的封装
- OkHttp面试之--OkHttp的整个异步请求流程
- OkHttp的使用--GET/POST(异步)
- okHttp的GET方法(异步)
- okhttp的异步请求
- okhttp的简单介绍(二)之简单封装
- okhttp的简单介绍(二)之简单封装
- OkHttp的同步和异步请求的实现
- okhttp 一 概述及同步和异步请求的实现
- 浏览器的异步实现原理
- Okhttp源码阅读之旅(二)
- okhttp中的Okio实现原理
- OkHttp的学习(二)
- 写一个Tomcat+Okhttp实现的聊天websocket聊天框架(二)--完成私聊功能
- OkHttp 3.7源码分析(二)——拦截器&一个实际网络请求的实现
- OkHttp 3.7源码分析(二)——拦截器&一个实际网络请求的实现
- first step
- java的LocalDate类使用
- value在input标签不同情况有不同的用法
- JS总结
- 为何在查询中索引未被使用 (Doc ID 1549181.1)
- OkHttp的实现原理(二)之异步
- ajax获取所有数据,前台分页,搜索
- 插入排序
- github 下载代码编译不过 apply plugin: 'com.github.dcendents.android-maven'
- 关于LTE终端的所谓的五模、七模、十频、十一频
- altium designer 常用快捷键小结
- JavaScript正则表达式
- 单例iOS
- Java中Integer值比较不注意的问题