Volley是Google在2003年的I/O大会上推出的通信框架,结合了AsyncHttpClient和Universal-Image-Loader的优点——简化了http的使用 + 异步加载图片的神奇能力。Android中的Http实现主要有HttpUrlConnection和HttpClient两种,关于二者的选择Google在Blog中表示推荐在姜饼小人(API level = 9)及以上的版本中使用Java的HttpUrlConnection而在之前的版本使用Apache的HttpClient,这在Volley这个框架中也有明确的体现。
 
获取Volley
git clone https://android.googlesource.com/platform/frameworks/volley
把它编译成jar文件就可以加入libs了
 
一、简单的请求(以StringRequest为例)
  Http的通信最主要的部分应该就是发出请求和接收响应了,所以Volley的比较核心的一个类就是RequestQueue,一个请求队列。它负责管理工作线程,读写缓存,和解析、分发响应(具体操作还是由具体的类实现),即将发出的Http请求都会首先聚集在这里等待工作线程来实现请求。RequestQueue可以被看成一艘载满Http请求的航空母舰,而工作线程就是弹射器喽。
  所以按照航母起飞飞机的步骤,我们可以猜到利用Volley进行Http通信的简单步骤:
    1.获取RequestQueue(得到一艘航母,可以是自己造的,也可以是委托别人造的,下面会提到)
    2.实例化一个Request(得到一架飞机,你也知道飞机又很多类型啦)
    3.将Request加入RequestQueue,等待工作线程将其发送出去(把飞机从机库升上起飞甲板,等待弹射器把它扔出去)
 
起飞侦察机-发出GET请求
  按照上面的步骤,第一步就是建立一个请求队列,最简单的方法就是用Volley.newRequestQueue(),这是一个特别方便的静态方法,替我们默认实现了所有需要的东西(网络、缓存等,这些在Volley中都有默认实现),它会返回一个已经开始运行的RequestQueue(相当于别人帮忙造了艘航母)。之后我们需要的只是设置好请求的响应监听接口,把请求加入到这个队列中就可以等着响应数据来敲门了。下面是Google文档中的示例代码:
 1   //初始化一个请求队列
2 RequestQueue queue = Volley.newRequestQueue(this);
3 String url ="http://www.google.com";
4
5 //根据给定的URL新建一个请求
6 StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
7 new Response.Listener() {
8 @Override
9 public void onResponse(String response) {
10 //在这里操作UI组件是安全的,因为响应返回时这个函数会被post到UI线程来执行
11 // 在这里尽情蹂躏响应的String。
12 }
13 }, new Response.ErrorListener() {
14 @Override
15 public void onErrorResponse(VolleyError error) {
16 // 出错了怎么办?凉拌!并且在这里拌。
17 }
18 });
19 // 把这个请求加入请求队列
20 queue.add(stringRequest);
StringRequest是Request的具体实现之一,代表解析后的响应数据是一个字符串,相似的还有JsonRequest(包括JsonObjectRequest和JsonArrayRequest两个可以使用的子类)、ImageRequest来满足基本的使用,用法大同小异。主要是构造参数不一样,分别如下:

  1.public StringRequest(int method, String url, Listener<String> listener,ErrorListener errorListener);

     参数说明:从左到右分别是请求方法(都封装在Request中的Method接口内),请求URL,响应监听接口实例,错误监听接口实例。

  2.public JsonObjectRequest(int method, String url, JSONObject jsonRequest,Listener<JSONObject> listener, ErrorListener errorListener);
     public JsonObjectRequest(String url, JSONObject jsonRequest, Listener<JSONObject> listener,ErrorListener errorListener);
     参数说明:如果是GET请求的话,jsonRequest传入null就可以了,否则在未指明请求方法的情况下(也就是第二个构造函数)会默认为POST请求。其他同上。
  3.public JsonArrayRequest(String url, Listener<JSONArray> listener, ErrorListener errorListener);
     参数说明:同上。
  4.public ImageRequest(String url, Response.Listener<Bitmap> listener, int maxWidth, int maxHeight,Config decodeConfig, Response.ErrorListener errorListener);
     参数说明:decodeConfig是图片的颜色属性,下面的几个值都可以使用。
 
Bitmap.Config中的颜色属性(枚举类型)
ALPHA_8  
ARGB_4444 由于质量低,已经被弃用,推荐用ARGB_8888
ARGB_8888 每个像素用4byte存储
RGB_565 每个像素用2byte存储,红色占5位,绿色占6位,蓝色占5位
 
起飞战斗机-发出POST请求
  基本方式和上面一样,但是怎么装导弹,啊不,是怎么提交的数据呢?
Volley会在Request的请求方法是POST(还有PUT和PATCH)的情况下调用Request类(就是XXXRequest的父类)的getParam()函数来获取参数,提前剧透,如果使用的是HttpUrlConnection的话,调用getParam()是在HurlStatck中的addBodyIfExists()函数实现的,感兴趣的话可以去看一下哈。所以,POST请求像下面这样就可以了。
 1 //初始化一个请求队列
2 RequestQueue queue = Volley.newRequestQueue(this);
3 String url ="http://www.google.com";
4
5 //根据给定的URL新建一个请求
6 StringRequest stringRequest = new StringRequest(Request.Method.POST, url,
7 new Response.Listener() {
8 @Override
9 public void onResponse(String response) {
10 // 在这里处理请求得到的String类型的响应
11 }
12 }, new Response.ErrorListener() {
13 @Override
14 public void onErrorResponse(VolleyError error) {
15 // 在这里进行出错之后的处理
16 }
17 }) {
18 @Override
19 protected Map<String, String> getParams() throws AuthFailureError {
20
21 Map<String, String> map = new HashMap<String, String>();
22 map.put("params1", "value1");
23 map.put("params2", "value2");
24 return map
25 };
26 // 把这个请求加入请求队列
27 queue.add(stringRequest);
 
后悔药-取消请求
  Request中有一个cancel()方法,调用这个就可以取消当前请求了,但是取消到哪一个层次就不一定了,但是Volley可以保证响应处理函数(就是onResponse()和onErroeResponse())不会被调用。还有一个一起取消多个请求,就是在发出请求前调用Request的setTag()方法为每个请求加一个标签,这个方法的参数是Object,所以我们可以使用任何类型作为标签。这样就可以调用ReqiestQueue的cancelAll()函数取消一群标签了。比较常用的方法就是,将发出这个请求的Activity或者Fragment作为标签,并在onStop()中调用cancelAll()。
 
二、使用ImageLoader加载图片
  ImageLoader是一个可以实现图片异步加载的类,但已经不是继承与Request了。ImageLoader虽然是头神兽,但必须在主线程召唤它,否则会抛出错误IllegalStateException,可能是因为ImageLoader在图片返回时要直接操作ImageView,在主线程里操作UI组件才是安全的,so~
  用ImageLoader加载图片分三步
    1.创建ImageLoader
    2.获取一个ImageListener对象
    3.调用ImageLoader的get()方法获取图片
  ImageLoader的构造函数长成这样:public ImageLoader(RequestQueue queue, ImageCache imageCache);
所以实例化一个ImageLoader需要一个RequestQueue(之前建立的就行),还有一个ImageCache,这是一个ImageLoader内部定义的接口,用来实现L1缓存——内存缓存(Volley在RequestQueue中已经实现了L2缓存——文件缓存)。ImageLoader中并没有对传入的ImageCache在使用前判空的代码,传null进去会出错的。如果实在不想弄内存缓存,实现一个什么都不做的ImageCache就好了。下面是代码:
 1 ImageLoader imageLoader = new ImageLoader(mRequestQueue, new ImageCache() {
2 @Override
3 public void putBitmap(String url, Bitmap bitmap) {
4 }
5
6 @Override
7 public Bitmap getBitmap(String url) {
8 return null;
9 }
10 });
11
12 //default_image是正在加载图片时占位用的
13 //error_image是加载不成功时显示的图片
14 ImageListener listener = ImageLoader.getImageListener(imageView, R.drawable.default_image, R.drawable.error_image);
15imageLoader.get("your image url", listener);
  除了ImageLoader之外Volley中还有一个Image加载的神器——NetworkImageView,使用步骤如下:
    1.在布局文件中加入控件,并在Java代码中获取实例
    2.设置default_image,error_image,图片URL,一个ImageLoader对象
  代码如下:
1 networkImageView = (NetworkImageView) findViewById(R.id.network_image_view);
2 networkImageView.setDefaultImageResId(R.drawable.default_image);
3 networkImageView.setErrorImageResId(R.drawable.error_image);
4 networkImageView.setImageUrl("your image url", imageLoader);
三、Google推荐的用法
  上面就是Volley的基本用法了,但是如果一个App需要频繁的网络通信的话,建立多个RequestQueue是件很奇怪的事儿(谁会因为临时有飞机要在海上起飞就去新建一艘航母呢,这得多有钱啊),所以Google推荐我们只实例化一个RequestQueue来应付频繁的Http通信,当然,要保证队列的寿命和App一样长。如何实现呢?Google又说了,不推荐在App的Application.onCretae()方法中实例化一个RequestQueue(不过确实是个简单的方法哈),最好是建立一个单例模式的类,并把所有我们需要用到的Volley的瓶瓶罐罐都放进去,这样显得更模块化。下面就是示例代码。这段代码中最重要的就是RequestQueue要用Application的Context实例化,要不然就会随着Activity的生命周期不停重建。其实,像AsyncHttpClient中的纯静态使用方法也不错(详情见:http://loopj.com/android-async-http/)
PS:下面还实现了一个简单的ImageCache
 1 private static MySingleton mInstance;
2 private RequestQueue mRequestQueue;
3 private ImageLoader mImageLoader;
4 private static Context mCtx;
5
6 private MySingleton(Context context) {
7 mCtx = context;
8 mRequestQueue = getRequestQueue();
9
10 mImageLoader = new ImageLoader(mRequestQueue,
11 new ImageLoader.ImageCache() {
12 private final LruCache<String, Bitmap>
13 cache = new LruCache<String, Bitmap>(20);
14
15 @Override
16 public Bitmap getBitmap(String url) {
17 return cache.get(url);
18 }
19
20 @Override
21 public void putBitmap(String url, Bitmap bitmap) {
22 cache.put(url, bitmap);
23 }
24 });
25 }
26
27 public static synchronized MySingleton getInstance(Context context) {
28 if (mInstance == null) {
29 mInstance = new MySingleton(context);
30 }
31 return mInstance;
32 }
33
34 public RequestQueue getRequestQueue() {
35 if (mRequestQueue == null) {
36 // getApplicationContext()是关键, 它会避免
37 // Activity或者BroadcastReceiver带来的缺点.
38 mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext());
39 }
40 return mRequestQueue;
41 }
42
43 public <T> void addToRequestQueue(Request<T> req) {
44 getRequestQueue().add(req);
45 }
46
47 public ImageLoader getImageLoader() {
48 return mImageLoader;
49 }
50 }
四、Volley是怎么管理请求的呢?
  RequestQueue会维护一个缓存调度线程(cache线程)和一个网络调度线程池(net线程)(注意,这是一池子线程),当一个Request被加到队列中的时候,cache线程会把这个请求进行筛选:如果这个请求的内容可以在缓存中找到,cache线程会亲自解析相应内容,并分发到主线程(UI)。如果缓存中没有,这个request就会被加入到另一个NetworkQueue,所有真正准备进行网络通信的request都在这里,第一个可用的net线程会从NetworkQueue中拿出一个request扔向服务器。当响应数据到的时候,这个net线程会解析原始响应数据,写入缓存,并把解析后的结果返回给主线程。如下图:
 
所以,读源码的话也可以把源码分成四层,如下图:(其余的类都可以归到“方便的工具类”中,比如ImageLoader,ClearCacheRequest等等)。

Volley的基本使用(转)的更多相关文章

  1. 快速Android开发系列网络篇之Volley

    Volley是Google推出的一个网络请求库,已经被放到了Android源码中,地址在这里,先看使用方法 RequestQueue mRequestQueue = Volley.newRequest ...

  2. Android Volley

    1.volley简单的介绍: Volley是一个HTTP库,使Android应用程序变得更加容易,最重要的是,网络 得更快. Vollry 提供以下好处: 1.自动调度的网络请求. 2.多个并发的网络 ...

  3. volley用法之 以post方式发送 json 参数

    需求是这样 我们需要发送一个post请求向服务器要参数.要求是发送的post参数也要是json格式. 简单一点的是这样的: 如果要发送的是这样简单的json格式,我们可以简单的使用map来实现: Re ...

  4. Volley框架使用笔记

    1.初始化请求队列 RequestQueue RequestQueue queue= Volley.newRequestQueue(context); 2.StringRequest 网络请求 Get ...

  5. android之volley学习

    Volley是android的平台通信库,一个新的网络通信框架.Volley 的特点:适合数据量小,通信频繁的网络操作. 获取Volley git 工具使用:git clone https://and ...

  6. Android开发学习之路-Volley源码解析

    从简单的StringRequest入手看看Volley的工作机制. 先简单说下Volley的用法: ① 获取一个RequestQueue mRequestQueue = Volley.newReque ...

  7. ym—— Android网络框架Volley(体验篇)

    VolleyGoogle I/O 2013推出的网络通信库,在volley推出之前我们一般会选择比较成熟的第三方网络通信库,如: android-async-http retrofit okhttp ...

  8. Google开源库-Volley的使用

    一.什么是Volley? Volley is an HTTP library that makes networking for Android apps easier and most import ...

  9. [Android]Volley源码分析(五)

    前面几篇通过源码分析了Volley是怎样进行请求调度及请求是如何被实际执行的,这篇最后来看下请求结果是如何交付给请求者的(一般是Android的UI主线程). 类图:

  10. [Android]Volley源码分析(四)

    上篇中有提到NetworkDispatcher是通过mNetwork(Network类型)来进行网络访问的,现在来看一下关于Network是如何进行网络访问的. Network部分的类图:

随机推荐

  1. discuz二次开发技巧

    discuz二次开发技巧 二次开发大多时候知识设置和处理,如果能够获知模板文件获得的变量数组将大大提高我们的开发效率 获取页面已经定义的变量 <--{eval printf_r(get_defi ...

  2. Python开发【第一章】:Python简介和入门

    Python简介 Python的创始人为Guido van Rossum.1989年圣诞节期间,在阿姆斯特丹,Guido为了打发圣诞节的无趣,决心开发一个新的脚本解释程序,做为ABC 语言的一种继承. ...

  3. C# asp:Repeater DataSource List<T>

    1. asp:Repeater 数据源为List<T> 2.页面显示 3.行绑定取值

  4. ThinkPHP 3.2 模板使用函数

    {$name|md5|strtoupper|substr=0,3} 编译后的结果是: <?php echo (substr(strtoupper(md5($name)),0,3));?> ...

  5. InfiniBand技术简介

    InfiniBand技术简介   转载请在文首保留原文出处:EMC中文支持论坛https://community.emc.com/go/chinese 介绍         随着CPU和通讯处理速度的 ...

  6. 自动文档摘要评价方法:Edmundson,ROUGE

    自动文档摘要评价方法大致分为两类: (1)内部评价方法(Intrinsic Methods):提供参考摘要,以参考摘要为基准评价系统摘要的质量.系统摘要与参考摘要越吻合, 质量越高. (2)外部评价方 ...

  7. Unity干中学——如何实现类似Windows Store 应用程序和Android Toast的通知?

    要实现通知中心功能,首先要创建一个游戏物体,在上面挂载GUITeture和GUIText脚本.注意GUITexture和GUIText脚本的顺序,GUITexture在前,GUIText在后,否则GU ...

  8. 转:小心,apc可能导致php-fpm罢工!

    原文来自于:http://www.searchtb.com/2014/02/apc-lock-php-fpm.html 最近线上产品出现了502错误.一般出现502错误,都是php-fpm 进程处理请 ...

  9. 转: 静态模式makefile中$(cobjs): $(obj)/%.o: $(src)/%.c

    4.12 静态模式静态模式规则是这样一个规则:规则存在多个目标,并且不同的目标可以根据目标文件的名字来自动构造出依赖文件.静态模式规则比多目标规则更通用,它不需要多个目标具有相同的依赖.但是静态模式规 ...

  10. 物联网传输协议MQTT

    MQTT是一个物联网传输协议,它被设计用于轻量级的发布/订阅式消息传输,旨在为低带宽和不稳定的网络环境中的物联网设备提供可靠的网络服务.MQTT是专门针对物联网开发的轻量级传输协议.MQTT协议针对低 ...