Okhttp同步请求源码分析

0
回复
250
查看
[复制链接]

49

主题

49

帖子

423

安币

攻城狮

Rank: 3Rank: 3

发表于 2019-2-1 09:40:01 | 显示全部楼层 |阅读模式
如果对本篇文章感兴趣,请前往,原文地址:http://www.apkbus.com/blog-868373-79475.html

进阶android,OKhttp源码分析——同步请求的源码分析OKhttp是我们经常用到的框架,作为开发者们,我们不单单要学会灵活使用,还要知道他的源码是如何设计的。今天我们来分析一下OKhttp 同步请求的执行流程和源码分析so,老样子,我们先来一张图![ ](https://upload-images.jianshu.io/upload_images/14371339-7d4571e8dfe44d4a.png?imageMogr2/auto-orient/strip|imageView2/2/w/1240)从上图可以看出,不管是同步请求还是异步请求,我们都需要创建一个OKhttpClient对象,用到的是build构造者模式,创建Request对象,然后再OKhttpClient的newCall方法和Request来封装我们的call对象。创建我们的实际请求的call对象,从上图可以看到,对于同步请求,我们调用的是excute方法,异步请求调用的是equeue方法。我们看一下做简单使用``` OkHttpClient okHttpClient = new  OkHttpClient.Builder()                .readTimeout(10, TimeUnit.SECONDS)                .build();        Request request = new Request.Builder().url("https://blog.csdn.net/androidstarjack").build();        Call call = okHttpClient.newCall(request);        try {            call.execute();//同步请求            call.enqueue(new Callback() {//异步请求                @Override                public void onFailure(Call call, IOException e) {                }                @Override                public void onResponse(Call call, Response response) throws IOException {                }            });        } catch (IOException e) {            e.printStackTrace();        }```我们先看一下okhttp的build   ![ ](https://upload-images.jianshu.io/upload_images/14371339-2d17c70b8c4bfafe.png?imageMogr2/auto-orient/strip|imageView2/2/w/1240)首先我们通过源码可以看出,okhttp的创建时通过build方法来创建的,其中初始化了一些事情,比如创建一个dispatcher拦截器,和一个连接池,连接池只要是链接状态的保存以及复用。build是要是创建 okhttp是所需要的参数。在创建Request创建的时候也是用构造者模式进行创建的,源码如下:```  Builder(Request request) {      this.url = request.url;      this.method = request.method;      this.body = request.body;      this.tag = request.tag;      this.headers = request.headers.newBuilder();    }```request的build构造里面初始化了一些请求的URL,请求方法哈请求头等请求报文的一些信息。Call对象 是通过他的父亲RealCall来完成的。![ ](https://upload-images.jianshu.io/upload_images/14371339-2df67b5e09791003.png?imageMogr2/auto-orient/strip|imageView2/2/w/1240)Call对象持有了Okhttp 和Request两个对象,同时呢还创建了一个缓存拦截器RetryAndFollowUpInterceptor,用于所需要的重定向操作。通过调用okhttpClient的newCAll来完成CALL的新建,进行相应的操作紧接着调用execute方法来完成同步请求!```@Override public Response execute() throws IOException {    synchronized (this) {      if (executed) throw new IllegalStateException("Already Executed");      executed = true;    }    captureCallStackTrace();    eventListener.callStart(this);    try {      client.dispatcher().executed(this);      Response result = getResponseWithInterceptorChain();      if (result == null) throw new IOException("Canceled");      return result;    } catch (IOException e) {      eventListener.callFailed(this, e);      throw e;    } finally {      client.dispatcher().finished(this);    }  }```//布尔值executed表示一个okhttp请求只能运行执行一次,然后开启捕捉一些错误堆栈信息,点用一个eventListener监听方法,接卸来是调用分发器的executed方法。这才是重中之重。```... client.dispatcher().executed(this);...```client.dispatcher返回一个分发器。然后通过分发器来执行操作:![ ](https://upload-images.jianshu.io/upload_images/14371339-582ac4201923b990.png?imageMogr2/auto-orient/strip|imageView2/2/w/1240)在同步请求中,调用executed方法,很简单酒吧这个Call对象添加到队列当中。Dispatcher的作用主要是维持call请求发给他 的状态,同时维护了一个线程池,开启了网络请求。从源码中我们可以看到Dispatcher ![ ](https://upload-images.jianshu.io/upload_images/14371339-0d71aee400a81e79.png?imageMogr2/auto-orient/strip|imageView2/2/w/1240)这几个请求队列代表着不同状态下的请求情况。紧接着通过拦截器链依次调用执行操作。最后还调用了Finish方法![ ](https://upload-images.jianshu.io/upload_images/14371339-c4ab8c98bdb21295.png?imageMogr2/auto-orient/strip|imageView2/2/w/1240)注意第三个参数,为false,这个方法的主要作用就是移除当前的请求,如果不能移除的话,返回异常,我们可以注意到,同步请求不需要调用promoteCalls,只有在异步请求的时候才会调用到,这个方法以后我们在讲。最后判断,正在将要执行的请求队列集合为0并且闲调用的回调不为null时,调用其run方法。此时,同步方法执行完成。 ![ ](https://upload-images.jianshu.io/upload_images/14371339-f4992a4992889a91.png?imageMogr2/auto-orient/strip|imageView2/2/w/1240)#### 阅读更多[**2018年技术文章汇总**](http://mp.weixin.qq.com/s?__biz=MzI3OTU0MzI4MQ==&mid=2247486901&idx=1&sn=9d9beb8925fa1dfaf87f1ba843ee3f6d&chksm=eb47612bdc30e83dd4e41bd0301fb642e872a2f0309ced346a7f94125cf496ef690d6047e0dd&scene=21#wechat_redirect)[**NDK项目实战—高仿360手机助手之卸载监听**](http://mp.weixin.qq.com/s?__biz=MzI3OTU0MzI4MQ==&mid=2247485690&idx=1&sn=44537ca3fcfb5347df3dde1a388cc4dc&chksm=eb476464dc30ed72a0a9f1cabd86375a0a18bd1478e8ca7e17bb7bcc81bc9ebc553b5f24c1f5&scene=21#wechat_redirect)[**(Android)面试题级答案(精选版)**](http://mp.weixin.qq.com/s?__biz=MzI3OTU0MzI4MQ==&mid=2247485690&idx=1&sn=44537ca3fcfb5347df3dde1a388cc4dc&chksm=eb476464dc30ed72a0a9f1cabd86375a0a18bd1478e8ca7e17bb7bcc81bc9ebc553b5f24c1f5&scene=21#wechat_redirect)如果对技术开发比较感兴趣,欢迎关注公众号:终端研发部。一起交流技术,进阶!  继续阅读全文



想在安卓巴士找到更多优质博文,可移步博客区

如果对本篇文章感兴趣,请前往,
原文地址:
http://www.apkbus.com/blog-868373-79475.html
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

领先的中文移动开发者社区
18620764416
7*24全天服务
意见反馈:1294855032@qq.com

扫一扫关注我们

Powered by Discuz! X3.2© 2001-2019 Comsenz Inc.( 粤ICP备15117877号 )