OkHttp详解一(封装Okhttp)

导读:

1 OkHttp的好处:

  • 对比一下就知道了,以前我用HttpClient和HttpURLConnection(注意URL都是大写)比较多,用在项目的时候,给用户的体验感觉总会出现这样那样的问题,比如跳转到一个新的页面的时候,内容就是加载不出来,简而言之就是不稳定。另外对于一些内存开销和系统开销都需要程序员自己来控制,比如线程池,甚至连接池的处理等等。其次,流量的优化问题自己处理起来也比较麻烦。
    OKhttp出来了这些问题都解决了。
    下面我们看看官方给的OkHttp的好处:

1.1 支持 SPDY ,共享同一个Socket来处理同一个服务器的所有请求;

那什么是SPDY呢?

它是HTTP的加强(不是取代),基于TCP协议,说白了目的就是让网络请求更快了

SPDY干了哪些事情做到这个的呢?
  • 单个TCP连接支持并发的HTTP请求。
  • 压缩报头和去掉不必要的头部来减少当前HTTP使用的带宽。
  • 定义一个容易实现,在服务器端高效率的协议。通过减少边缘情况、定义易解析的消息格式来减少HTTP的复杂性。
  • 强制使用SSL,让SSL协议在现存的网络设施下有更好的安全性和兼容性。
  • 允许服务器在需要时发起对客户端的连接并推送数据。
  • SPDY已被HTTP/2取代

1.2 如果SPDY不可用,则通过连接池来减少请求延时

什么叫连接池?两个主机建立连接是个很复杂的过程,经过多次数据包的交换,例如TCP的三次握手,每次连接都走这个过程岂不是很耗资源。连接池说白了就是就是为了避免每次都要经历这些连接过程,从而节省了资源,耗时更短。

1.3 无缝的支持GZIP来减少数据流量

小伙伴不知道什么是GZIP,没事,百度百科有讲解。大流量的WEB站点常常使用GZIP的压缩技术来让用户感受更快的速度。这一般是指WWW服务器中安装的一个功能,当有人来访问这个服务器中的网站时,服务器中的这个功能就将网页内容压缩后传输到来访的电脑浏览器中显示出来.一般对纯文本内容可压缩到原大小的40%.这样传输就快了,效果就是你点击网址后会很快的显示出来(优点).当然这也会增加服务器的负载(缺点).

1.4 缓存响应数据来减少重复的网络请求

okhttp只会对get请求进行缓存,post请求是不会进行缓存,这也是有道理的,因为get请求的数据一般是比较持久的,而post一般是交互操作,没太大意义进行缓存。我们get请求有时有不一样的需求,有时需要进行缓存,有时需要直接从网络获取,有时只获取缓存数据,这些处理,okhttp都有帮我们做了,我们做的只需要设置就是了。

2.如何封装这些API

在做项目的时候,网络请求包括get请求,post请求,文件上传等等,如果能有统一的接口来处理这些请求就好了。我研究了一下[张鸿洋](https://github.com/hongyangAndroid/okhttputils)发布在github上的代码,稍微进行了一点改动用在我们的项目之中。需要注意的是,有时候在公司项目中,有些类是需要的,读懂代码之后我们就可以很容易根据自己项目的需求来进行裁剪代码。

2.1 首先回顾一下OkHttp提供的原生接口

(一) get请求

//创建okHttpClient对象
OkHttpClient mOkHttpClient = new OkHttpClient();
//创建一个Request
final Request request = new Request.Builder()
                .url("https://github.com/hongyangAndroid")
                .build();
//new call
Call call = mOkHttpClient.newCall(request); 
//请求加入调度
call.enqueue(new Callback()
        {
            @Override
            public void onFailure(Request request, IOException e)
            {
            }

            @Override
            public void onResponse(final Response response) throws IOException
            {
                    //String htmlStr =  response.body().string();
            }
        });             

(二) post请求

FormEncodingBuilder builder = new FormEncodingBuilder();   
builder.add("username","张鸿洋");
Request request = new Request.Builder()
                   .url(url)
                .post(builder.build())
                .build();
 mOkHttpClient.newCall(request).enqueue(new Callback(){});

仔细观察原生api发现不管是post请求还是get请求,其实只是Request不同而已,其他所需要用到的类都一样。
另外它们Request也有相同的部分,可以抽取一个抽象基类,把相同的属性和方法抽取出来,增强代码的复用性。
下面这张图是代码结构预览图:

下面一一解释封装的思想

  • builder包下的类:引自Builder构造者模式,目的是为了保存数据
    OkHttpRequestBuilder 是抽象基类,抽取了公共属性和方法,例如url(String),headers(HashMap), params
    抽象方法public abstract RequestCall build(): 获取RequestCall对象

  • request包下的类:目的是为了构建不同的request
    OkHttpRequest: 构建Request的基类 1.通过Request.Builder设置url,tag,以及headers(抽取公共部分);2.抽象方法:buildRequestBody,当子类继承抽象类时,必须实现该方法(利用多态封装);3.build方法:实例化RequestCall(抽取公共部分
    GetRequest:由于是get请求,RequestBody为空
    PostFormRequest: post请求,实现requestBody

  • RequestCall: 实例化Call实例,触发OkHttpUtils执行execute方法

  • OkHttpUtils: 使用单例模式,保存唯一OkHttpClient对象,执行execute方法

3 所谓的难点:由于异步回调回来之后,依然是在子线程的,方法有很多,介绍一种使用线程池的方式

static class MainThreadExecutor implements Executor
        {
            private final Handler handler = new Handler(Looper.getMainLooper());

            @Override
            public void execute(Runnable r)
            {
                handler.post(r); //handler把Runnable弄到UI线程上执行
            }
        }
//调用
new MainThreadExecutor().execute(new Runnable()
        {
            @Override
            public void run()
            {
                callback.onResponse(object, id);
                callback.onAfter(id);
            }
        }

源码地址

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,542评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,596评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,021评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,682评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,792评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,985评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,107评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,845评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,299评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,612评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,747评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,441评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,072评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,828评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,069评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,545评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,658评论 2 350

推荐阅读更多精彩内容