网络请求之浅谈Volley的那些坑与改进(一)

深入Volley之前,有必要回顾下几个知识点:

1.HTTP0.9 -> HTTP1.0 ->HTTP1.1 ->HTTP2协议[注:为什么不是2.0,协议制定委员会说以后只存在HTTPX];Google—HTTP协议;

2.HTTP2优点:相比较HTTP1.1主要两大改进:1.可复用TCP连接;2.所有报文信息都将是二进制传输,采用GZIP或COMPRESS压缩方式;有必要百度下这两点的实际原理;

3.目前为什么国内很多网站没有HTTP全站替换HTTPS,速度是主要原因:想想SSL和TLS的握手还要加上HTTP默认TCP三次握手,测试显示增加访问时间3倍左右;

说明:本文不会具体分析每个类的作用。[每个类都很优美,例如ByteArrayPool这个类]

目前为止除了OkHttp的框架,个人认为遇到的最优秀网络请求框架,本文仅从以下几点谈下Volley:

1,高度可扩展性(支持https )

2,重定向url问题

3,协议内容类型 传参问题

4,Cache缓存机制

5,对大多数客户端封装的Volley数据展示层向上层抛出数据修改意见

1.高度可扩展性(支持https )

if (stack == null) {          

  if (Build.VERSION.SDK_INT >= 9) {                

stack = new HurlStack();          

  } else {                

// Prior to Gingerbread, HttpUrlConnection was unreliable.              

  // See: http://android-developers.blogspot.com/2011/09/androids-http-clients.html                stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent));          

  }        

}

volley提供了HttpStack抽象类,极大的扩展性,方便接入HttpURLConnection | OKHTTP等;在Android2.3之前,使用AndroidHttpClient是由于HttpURLConnection调用 close() 函数会影响连接池,导致连接复用失效,若使用需要关闭keepAlive,极大的不方便,每次HTTP请求都有。另外在HttpURLConnection 默认开启了 gzip 压缩,提高了 HTTPS 的性能,Android4.0 HttpURLConnection 支持了请求结果缓存。

2.重定向url问题

BasicNetwork.performRequest方法

 // Handle moved resourcesif (

statusCode == HttpStatus.SC_MOVED_PERMANENTLY || statusCode ==                  HttpStatus.SC_MOVED_TEMPORARILY) {            

    String newUrl = responseHeaders.get("Location");               

 request.setRedirectUrl(newUrl)

; }

这里可能会有问题,对于业务约定的只重定向GET请求且参数或Cookie不变的话没有问题,否则需要手动修改重定向参数;

3.协议内容类型 

传参问题Content-Type问题[参考http://www.alloyteam.com/2015/06/yong-volley-cai-di-keng/]

4,Cache缓存机制

[参考:http://www.a.codekk.com/detail/Android/grumoon/Volley%20源码解析]

Volley 构建了一套相对完整的符合 Http 语义的缓存机制。

优点和特点

(1). 根据Cache-Control和Expires首部来计算缓存的过期时间。如果两个首部都存在情况下,以Cache-Control为准。

(2). 利用If-None-Match和If-Modified-Since对过期缓存或者不新鲜缓存,进行请求再验证,并处理 304 响应,更新缓存。

(3). 默认的缓存实现,将缓存以文件的形式存储在 Disk,程序退出后不会丢失。缓存的再验证方面,在构建If-Modified-Since请求首部时,Volley 使用了服务端响应的Date首部,没有使用Last-Modified首部。整个框架没有使用Last-Modified首部。这与 Http 语义不符。private void addCacheHeaders(Mapheaders, Cache.Entry entry) {    // If there's no cache entry, we're done.    if (entry == null) {        return;    }    if (entry.etag != null) {        headers.put("If-None-Match", entry.etag);    }    if (entry.serverDate > 0) {        Date refTime = new Date(entry.serverDate);        headers.put("If-Modified-Since", DateUtils.formatDate(refTime));    }}服务端根据请求时通过If-Modified-Since首部传过来的时间,判断资源文件是否在If-Modified-Since时间 以后 有改动,如果有改动,返回新的请求结果。如果没有改动,返回 304 not modified。Last-Modified代表了资源文件的最后修改时间。通常使用这个首部构建If-Modified-Since的时间。Date代表了响应产生的时间,正常情况下Date时间在Last-Modified时间之后。也就是Date>=Last-Modified。通过以上原理,既然Date>=Last-Modified。那么我利用Date构建,也是完全正确的。可能的问题出在服务端的 Http 实现上,如果服务端完全遵守 Http 语义,采用时间比较的方式来验证If-Modified-Since,判断服务器资源文件修改时间是不是在If-Modified-Since之后。那么使用Date完全正确。可是有的服务端实现不是比较时间,而是直接的判断服务器资源文件修改时间,是否和If-Modified-Since所传时间相等。这样使用Date就不能实现正确的再验证,因为Date的时间总不会和服务器资源文件修改时间相等。尽管使用Date可能出现的不正确情况,归结于服务端没有正确的实现 Http 语义。但我还是希望 Volley 也能完全正确的实现 Http 语义,至少同时处理Last-Modified和Date,并且优先使用Last-Modified。

5,对大多数客户端封装的Volley数据展示层向上层抛出数据修改意见

目前响应靠new Thread向上抛数据会极大地可能造成线程竞争或死锁,同样也会内存抖动问题;/** 响应监听  **/    private ListenerresponseListener = new Listener() {        @Override        public void onResponse(final T response) {            if (mCanceled) {                // 如果取消了,直接返回                return;            }            new Thread(new Runnable() {                @Override                public void run() {                    Message message = mHandler.obtainMessage();                    message.obj = onNetResponse(response);                    mHandler.sendMessage(message);                }            }).start();        }    };建议实现线程池来处理,参考Volley的ExecutorDelivery类设计思想private ExecutorPostResult mExecutorPostResult = new ExecutorPostResult(new Handler(Looper.getMainLooper()));/** 响应监听  **/    private ListenerresponseListener = new Listener() {

@Override

public void onResponse(final T response) {

if (mCanceled) {

// 如果取消了,直接返回

return;

}

// 由于解析需要时间,启动子线程

mExecutorPostResult.postResponseResult(SuningNetTask.this,onNetResponse(response));

}

};

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

推荐阅读更多精彩内容