OkHttp 执行流程与为什么Callback在子线程中执行
来源:互联网 发布:中介管理系统源码 编辑:程序博客网 时间:2024/05/22 11:41
当通过自定义的接口Server返回一个Call对象后,要执行请求就要调用Call的
enQueue方法或者execute方法,由于execute方法是同步方法,所以略过。Call是一个接口,
真正执行该方法的是Call的实现类(仅此一个实现类)RealCall的enqueue方法如下
@Override public void enqueue(Callback responseCallback) { synchronized (this) { if (executed) throw new IllegalStateException("Already Executed"); executed = true; } captureCallStackTrace(); client.dispatcher().enqueue(new AsyncCall(responseCallback)); }
子类,而client.dispatcher 在我看来是一个线程池。然后这个线程池将我们的回调加入了队列,
然后是Dispatcher的enqueue方法的实现
synchronized void enqueue(AsyncCall call) { if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) { runningAsyncCalls.add(call); executorService().execute(call); } else { readyAsyncCalls.add(call); } }
runningAsyncCalls和readyAsyncCalls是Deque类型的集合,而这个Deque继承与Queue,所以
这是两个队列,从代码可以看出,这个请求一个加入了正在运行的队列,一个加入了准备队列,
准备,加入运行队列之后,接着执行了 executorService().execute(call);
public synchronized ExecutorService executorService() { if (executorService == null) { executorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS, new SynchronousQueue<Runnable>(), Util.threadFactory("OkHttp Dispatcher", false)); } return executorService; }
而executorService()方法返回了一个ExecutorService对象,该对象实现了Executor接口,而该
接口中,只有一个方法execute(),该方法官方文档给出的实现为
class SerialExecutor implements Executor { final Queue<Runnable> tasks = new ArrayDeque<Runnable>(); final Executor executor; Runnable active; SerialExecutor(Executor executor) { this.executor = executor; } public synchronized void execute(final Runnable r) { tasks.offer(new Runnable() { public void run() { try { r.run(); } finally { scheduleNext(); } } }); if (active == null) { scheduleNext(); } } protected synchronized void scheduleNext() { if ((active = tasks.poll()) != null) { executor.execute(active); } } }
从execute方法中我们可以看出,为什么callback在子线程调用了,那么接下来就是执行的最后一步,在run里进行了什么操作
来看下AsyncCall的构造方法和execute方法
AsyncCall(Callback responseCallback) { super("OkHttp %s", redactedUrl()); this.responseCallback = responseCallback; }
@Override protected void execute() { boolean signalledCallback = false; try { Response response = getResponseWithInterceptorChain(); if (retryAndFollowUpInterceptor.isCanceled()) { 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); } }
自这里调用了callback的onFailure和onResponse,那么这里似乎和上边的 SerialExecutor 中的 r.run() 并没有什么关系,那么让我们来看下NamedRunnable的父类
public abstract class NamedRunnable implements Runnable { protected final String name; public NamedRunnable(String format, Object... args) { this.name = Util.format(format, args); } @Override public final void run() { String oldName = Thread.currentThread().getName(); Thread.currentThread().setName(name); try { execute(); } finally { Thread.currentThread().setName(oldName); } } protected abstract void execute();}
这里可以看到NamedRunnable实现了Runnable并重写的run方法并在其中调用了execute()方法。到这里OkHttp请求流程完成
2 0
- OkHttp 执行流程与为什么Callback在子线程中执行
- 子线程中执行定时器
- 在子线程中 执行相关操作 请求网络
- QTcpSocket 在子线程执行测试笔记
- 子线程执行完后,主线程在执行场景
- Android中为什么主线程更新UI,子线程执行耗时操作?
- C#中Invoke与BeginInvoke在线程中的执行解析
- 子线程执行scheduledTimer
- 子线程执行方法
- 子线程执行进度条
- 线程执行流程
- C#将子线程附加在当前线程之后执行
- ios6.0中,UIAlertView不能在子线程中执行了
- 为什么不能直接在BroadCastReceiver中开一个线程执行耗时任务
- 执行主线程之后又执行了几个子线程,保证子线程执行完成在结束主线程
- Android子线程中直接回到UI线程执行
- C# 在子线程中创建不会阻塞执行的窗口
- [新手记录]在ProgressDialog中执行子线程取消的问题
- python——多重表达式
- android软件版本更新
- 解决Could not open Hibernate Session for transaction; nested exception is java.lang.NoClassDefFoundEr
- VS中配置opencv,使用imshow方法出现窗口名称乱码解决方案
- C++之静态数据成员与静态成员函数
- OkHttp 执行流程与为什么Callback在子线程中执行
- MySQL查询近一个月的数据
- 吴恩达机器学习笔记——softmax回归概率模型推导
- JavaScript模板引擎原理
- [构造 二分图] SRM 693 div1 BipartiteConstruction
- LeetCode之Number Complement
- Python——基础总结
- 无限“递归”的python程序
- 蓝桥杯带分数