Volley源码之使用方式和使用场景详解

 更新时间:2017年11月25日 09:57:04   作者:robert_chao  
这篇文章主要介绍了Volley源码之使用方式和使用场景详解,具有一定参考价值,需要的朋友可以了解下。

概述

Volley是Google在2013年推出的一个网络库,用于解决复杂网络环境下网络请求问题。刚推出的时候是非常火的,现在该项目的变动已经很少了。项目库地址为https://android.googlesource.com/platform/frameworks/volley

通过提交历史可以看到,最后一次修改距离今天已经有一段时间了。而volley包的release版本也已经很久没有更新了。

author JeffDavidson<jpd@google.com> SunMar1316:35:592016+0000虽然很久没有更新了,Volley始终是一个很好的网络框架,我们来分析一下volley的源码,更好的了解volley的使用场景,设计模式,还有存在的一些小问题,或者说使用不当出现的问题。

创建RequestQueue

下面的代码片段展示了建立一个RequestQueue需要的步骤:

// 使用 cache 和 network初始化 RequestQueue
mRequestQueue = new RequestQueue(cache, network);

// 启动队列
mRequestQueue.start();

String url ="http://www.example.com";

// 明确描述请求(request)并处理响应(response)
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
    new Response.Listener<String>() {
  @Override
  public void onResponse(String response) {
    // 处理响应信息
  }
},
  new Response.ErrorListener() {
    @Override
    public void onErrorResponse(VolleyError error) {
      // Handle error
  }
});

// 添加request 到 RequestQueue.
mRequestQueue.add(stringRequest);

// ...

Volley类实质上只提供了一个方法newRequestQueue,用来创建RequestQueue,RequestQueue是volley的请求队列,mCurrentRequests中存储了执行中的和将要执行的请求,DEFAULT_NETWORK_THREAD_POOL_SIZE是一个常量4。

可以通过RequestQueue的publicRequestQueue(Cachecache,Networknetwork,intthreadPoolSize)这个方法修改线程数量,默认开启4个线程,然后一直子后台运行。这里需要注意一下在调用Volley的RequestQueue的时候,内部已经调用了RequestQueue的start方法,不需要再次调用。如果自己创建RequestQueue需要自行调用start方法,整个APP的生命周期中使用一次即可。多次调用会增加线程开销,每次调用start方法,都会调用stop方法终止原来的线程,然后重新开启新的线程。

正常使用volley后台请求线程数量是固定的,默认4个并发不需要修改,可能是基于这个考虑,并没有使用Executor线程池,线程池的考虑本身是为了管理线程频繁创建,避免过多开销的。默认始终4个线程,不存在过度开销问题。个人感觉这里使用线程池会更好一些,当然引入线程池复杂度一定会增加。始终只有4个线程也引发了一些问题,使volley在某些场景不适用。如果请求服务器响应时间太长,4个线程都会处于阻塞状态,这个时候新来的请求只能等待,不能直接执行。volley是比较适合轻量级请求,请求频繁,请求时间短。

/** Number of network request dispatcher threads to start. */ 
private static final int DEFAULT_NETWORK_THREAD_POOL_SIZE = 4; 
public RequestQueue(Cache cache, Network network) { 
  this(cache, network, DEFAULT_NETWORK_THREAD_POOL_SIZE); 
} 
Network network = new BasicNetwork(stack); 
 
   RequestQueue queue = new RequestQueue(new DiskBasedCache(cacheDir), network); 
   queue.start(); 

请求执行者HttpStack

HttpStack是真正执行网络请求的接口,performRequest方法执行请求,源码中有两个实现,一个是HurlStack,另一个是HttpClientStack,SDK版本大于等于9使用的是HurlStack。

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)); 
   } 
 } 

DefaultHttpClient和它的兄弟AndroidHttpClient都是HttpClient具体的实现类,它们都拥有众多的API,而且实现比较稳定,bug数量也很少。但同时也由于HttpClient的API数量过多,使得我们很难在不破坏兼容性的情况下对它进行升级和扩展,所以目前Android团队在提升和优化HttpClient方面的工作态度并不积极。

HttpURLConnection是一种多用途、轻量极的HTTP客户端,使用它来进行HTTP操作可以适用于大多数的应用程序。虽然HttpURLConnection的API提供的比较简单,但是同时这也使得我们可以更加容易地去使用和扩展它。不过在Android2.2版本之前,HttpURLConnection一直存在着一些令人厌烦的bug。比如说对一个可读的InputStream调用close方法时,就有可能会导致连接池失效了。那么我们通常的解决办法就是直接禁用掉连接池的功能。Android2.3版本之前HttpURLConnection存在bug不建议使用,而在Android2.3版本及以后,HttpURLConnection则是最佳的选择。它的API简单,体积较小,因而非常适用于Android项目。压缩和缓存机制可以有效地减少网络访问的流量,在提升速度和省电方面也起到了较大的作用。

目前来说,我们有一个更好的请求选择okhttp,volley源码中并没有封装它的请求,我们可以自己实现HttpStack接口,在performRequest使用okhttp请求。OkHttp相较于其它的实现有以下的优点:支持SPDY,允许连接同一主机的所有请求分享一个socket。如果SPDY不可用,会使用连接池减少请求延迟。使用GZIP压缩下载内容,且压缩操作对用户是透明的。利用响应缓存来避免重复的网络请求。当网络出现问题的时候,OKHttp会依然有效,它将从常见的连接问题当中恢复。如果你的服务端有多个IP地址,当第一个地址连接失败时,OKHttp会尝试连接其他的地址,这对IPV4和IPV6以及寄宿在多个数据中心的服务而言,是非常有必要的。使用OkHttp作为替代是一个很好的选择。

缓存与线程处理

刚才说有4个默认线程是不准确的,是有4个NetworkDispatcher执行网络请求,还有一个CacheDispatcher缓存线程,本地缓存策略需要实现Cache接口,源码中有两个实现DiskBasedCache,NoCache,默认使用的是DiskBasedCache。我们可以根据自己的需要实现Cache接口。DiskBasedCache默认路径是app缓存目录下的volley,默认缓存5M,超出之后会覆盖旧数据。

Request类

Request类的子类相当于volley的输入,是创建请求的时候用的。JsonObjectRequest、JsonArrayRequest用来处理返回是json的数据,StringRequest处理stirng,ImageRequest用来处理图片。

Volley其实是一个生产者和消费者系统,调用方是生产者,而Volley是消费者。调用方通过RequestQueue生产Request,而Vollery消费Request从而得到Response。那么负责调配这些生产者和消费者的就是Dispatcher,分别是Cache和Network的Dispatcher。

总结

以上就是本文关于Volley源码之使用方式和使用场景详解的全部内容,希望对大家有所帮助。如有不足指出,欢迎留言指出。感谢朋友们对本站的支持!

相关文章

  • Android实现一个简单带动画的展开收起功能

    Android实现一个简单带动画的展开收起功能

    今天给大家带来一个展开和收起的简单效果,如果只是代码中简单设置显示或隐藏,熟悉安卓系统的朋友都知道,那一定是闪现,所以笔者结合了动画,使得体验效果瞬间提升一个档次,感兴趣的小伙伴可以自己动手试一试
    2023-08-08
  • Android开发实现的导出数据库到Excel表格功能【附源码下载】

    Android开发实现的导出数据库到Excel表格功能【附源码下载】

    这篇文章主要介绍了Android开发实现的导出数据库到Excel表格功能,涉及Android数据库及Excel表格相关操作技巧,并附带完整源码供读者下载参考,需要的朋友可以参考下
    2018-03-03
  • 总结Android App内存优化之图片优化

    总结Android App内存优化之图片优化

    网上有很多大拿分享的关于Android性能优化的文章,主要是通过各种工具分析,使用合理的技巧优化APP的体验,提升APP的流畅度,但关于内存优化的文章很少有看到。下面是我在实践过程中使用的一些方法,很多都是不太成熟的项目,只是将其作为一种处理方式分享给大家。
    2016-08-08
  • Android实现手机壁纸改变的方法

    Android实现手机壁纸改变的方法

    这篇文章主要介绍了Android实现手机壁纸改变的方法,以完整实例形式分析了Android手机壁纸改变的方法,包括页面布局及属性设置的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-09-09
  • android自由改变Dialog窗口位置的方法

    android自由改变Dialog窗口位置的方法

    这篇文章主要介绍了android自由改变Dialog窗口位置的方法,涉及Android操作Dialog窗口相关技巧,需要的朋友可以参考下
    2015-04-04
  • Gradle的安装和环境变量的配置详解

    Gradle的安装和环境变量的配置详解

    这篇文章主要介绍了Gradle的安装和环境变量的配置详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-07-07
  • Android实现自适应屏幕的弹窗广告

    Android实现自适应屏幕的弹窗广告

    这篇文章主要为大家详细介绍了Android实现自适应屏幕的弹窗广告,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-07-07
  • Android动态加载布局实现技巧介绍

    Android动态加载布局实现技巧介绍

    通过使用LayoutInflater 每次点击按钮时候去读取布局文件,然后找到布局文件里面的各个VIEW 操作完VIEW 后加载进我们setContentView 方面里面的要放的布局文件里面,每次动态加载文件必需调用 removeAllViews方法,清除之前的加载进来的View
    2022-12-12
  • android读取raw文件示例

    android读取raw文件示例

    这篇文章主要介绍了android读取raw文件示例,需要的朋友可以参考下
    2014-02-02
  • Android开发中自定义ProgressBar控件的方法示例

    Android开发中自定义ProgressBar控件的方法示例

    这篇文章主要介绍了Android开发中自定义ProgressBar控件的方法,结合实例形式分析了自定义ProgressBar控件的定义与使用方法,需要的朋友可以参考下
    2017-10-10

最新评论