手记

【九月打卡】第7天 开源框架 OkHttp 源码解读

课程名称BAT大牛亲授技能+技巧 Android面试快速充电升级
课程章节:Android基础相关面试问题
主讲老师DocMike

课程内容

OkHttp 是 Square 开源的轻量级的网络请求框架。

1.OkHttp 同步请求过程

  1. 创建一个 OkHttpClient 对象,默认使用 new OkHttpClient() 创建对象,如果需要初始化网络请求的参数,可以通过内部的 Builder 的 build() 方法来创建。
  2. 创建 Request 对象和 Response 对象。
  3. 通过 Call 对象的 execute() 方法来操作请求。
  4. Call 对象的实现逻辑是通过 RealCall 来完成的。execute() 方法只能被执行一次,如果已经被执行过,再次被调用会抛出异常。调度器 Dispatcher 会将同步请求添加到队列中,通过拦截器链做实际的网络请求操作。
  5. 执行完毕之后将同步请求从 Dispatcher 移除。

2.OkHttp 异步请求过程

  1. 生成一个 OkHttpClient 对象;
  2. 创建 request 对象;
  3. 通过 Call 对象的 enqueue() 方法来操作请求,异步回调 Callback 的 onFailure()、onResponse() 都是在子线程回调的。
  4. 拦截器链完成实际的网络请求操作。

可以发现,OkHttp异步请求与同步请求的过程相比,区别仅仅是 Call 对象调用的方法不同。同步请求调用 execute()方法,异步请求调用 enqueue() 方法。

3.总结

OkHttp的高效体现在,OkHttp内有个 Dispatcher 类,是 OkHttp 内部维护的一个线程池,对最大连接数,host 最大访问量做了初始定义。维护3个队列及1个线程池。

  1. readyAsyncCalls,待访问请求队列,里面存储准备执行的请求。
  2. runningAsyncCalls,异步请求队列,里面存储正在执行,包含已经取消但是还没有结束的请求。
  3. runningSyncCalls,同步请求队列,正在执行的请求,包含已经取消但是还没有结束的请求。
  4. ExecutorService,线程池,最小0,最大为 Integer.Max 的线程池,0 表示线程空闲不会被保留。线程池中的线程数量大于核心线程数时,空闲线程等待 keepAliveTime 的时长为 60s,之后被停止。

同步请求在执行 call.excute() 的时候,调用到 realcall 类里的 excute() 方法,这个是同步方法。在方法的第一行就加了锁,判断 executed 标记,如果是 true 就抛出异常,保证一个请求只被执行一次。false 的话继续向下执行。调用 client.dispatcher.excute() 进入到 dispatcher 类中,向 runningSyncCalls 队列中添加当前这个请求,执行结束会调用 finished() 方法。

如果是异步操作,会创建一个 RealCall.AsyncCall 对象,AsyncCall 继承的 NamedRunnable 接口,NamedRunnable 是个 runnable。进入到 Dispatcher 的 enqueue() 方法中,首先判断线程池中线程的数据,host 的访问量,如果都没有达到那么加入到 runningAsyncCalls 中并执行。否则加入到 readyAsyncCalls 队列中。如果是异步操作调用 finished() 方法,让后调用 promoteCall() 方法,在 promoteCalls() 中用迭代器遍历 readyAsyncCalls,然后加入到 runningAsyncCalls 中。

课程总结

OkHttp 网路框架在 Android 开发中应用非常广,在看源码时,不仅要研究网络请求的实现过程,还要体会框架的设计思想,查看源码可知,在 OkHttp 框架的源码中给出了 7 个拦截器,每个拦截器都分别执行不同的任务。此外还引入了连接池的思想,还用到了责任链模式、建造者模式、工厂模式、观察者模式等等。


0人推荐
随时随地看视频
慕课网APP