Volley学习小结

简介:

1、概述

volley英文即是“齐射,并发”,是谷歌在2013年推出的网络通信库,有如下特点:

【1】通信更快,更简单

【2】Get、Post网络请求以及网络数据图像的高效的异步请求

【3】对网络优先级排序处理

【4】网络请求缓存,可以将上次数据进行简单缓存

【5】可以多级别取消请求

【6】可以和Activity生命周期的联动,在Activity销毁时可以结束网络请求操作


Volley在性能方面也进行了大幅度的调整,它的设计目标就是非常适合去进行数据量不大,但通信频繁的网络操作,而对于大数据量的网络操作,比如说下载文件等,Volley的表现就会非常糟糕。

2、Volley框架使用之网络请求

【Volley的get和post请求方式的使用】

也是对Android原生的get和psot进行了二次封装和优化,首先要挑选一个合适的请求对象

StringRequest:对请求数据结果类型不确定的情况下使用,该类型可以涵盖后面2种类型

JsonObjectRequest:确定是jsonObject时使用

JsonArrayRequest:确定是jsonArray时使用


【Volley的网络请求队列建立和取消】

首先要建立一个全局的请求队列,每次建立的请求加入到这个全局队列中,这样方便同意添加删除等管理

【Volley与Activity生命周期的联动】

将网络请求与Activity绑定在了一起,防止当Activity销毁时请求依然存在造成内存溢出,通常是将请求设置Tag标签,在onStop()中执行取消请求

【Volley的简单二次回调封装】

满足全局使用的一个方式可控,可自定义定制需求

在写代码之前首先要找到volley的jar包http://download.csdn.net/detail/inquisitive_plus/8488223#comment ,然后如何导入jar包到Android Studio中参考

http://jingyan.baidu.com/article/e6c8503c7190b7e54f1a1893.html

【代码实现】

这里给出一些关键代码,完整代码会在最后给出

Volley请求队列需要一个全局的,因此我们需要把他写到一个全局的Apllication中

[java]  view plain  copy
  1. <span style="font-size:18px;">public class MyApplication extends Application {  
  2.     //定义全局的网络请求队列  
  3.     public static RequestQueue queues;  
  4.     @Override  
  5.     public void onCreate() {  
  6.         super.onCreate();  
  7.         queues = Volley.newRequestQueue(getApplicationContext());  
  8.     }  
  9.     //获取请求队列  
  10.     public static RequestQueue getHttpQueues(){  
  11.         return queues;  
  12.     }  
  13. }</span>  

然后在MAinActivity中给出StringResponse的方式,这里主要有四个参数 请求方式,url,请求成功回调函数,请求失败回调函数

Get方式URL直接携带参数

Get:String方式

[java]  view plain  copy
  1. <span style="font-size:18px;">private void Volley_StringGet() {  
  2.         /*这里使用StringRequets*/  
  3.         String url = "http://ip.taobao.com/service/getIpInfo.php?ip=125.71.229.221";  
  4.         StringRequest request = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {  
  5.             @Override  
  6.             public void onResponse(String s) {  
  7.                 Toast.makeText(MainActivity.this, s, Toast.LENGTH_LONG).show();  
  8.   
  9.             }  
  10.         }, new Response.ErrorListener() {  
  11.             @Override  
  12.             public void onErrorResponse(VolleyError volleyError) {  
  13.                 Toast.makeText(MainActivity.this, volleyError.toString(), Toast.LENGTH_LONG).show();  
  14.   
  15.             }  
  16.         });  
  17.         /*请求对象设置Tag标签,并加入全局队列*/  
  18.         request.setTag("StringGet");  
  19.         MyApplication.getHttpQueues().add(request);  
  20.   
  21.     }</span>  
Get:Json方式
[java]  view plain  copy
  1. <span style="font-size:18px;">private void Volley_JsonGet() {  
  2.         /*这里使用JsonRequets*/  
  3.         String url = "http://ip.taobao.com/service/getIpInfo.php?ip=125.71.229.221";  
  4.         JsonObjectRequest request = new JsonObjectRequest(Request.Method.POST, url, nullnew Response.Listener<JSONObject>() {  
  5.             @Override  
  6.             public void onResponse(JSONObject js) {  
  7.                 Toast.makeText(MainActivity.this, js.toString(), Toast.LENGTH_LONG).show();  
  8.   
  9.             }  
  10.         },  
  11.                 new Response.ErrorListener() {  
  12.                     @Override  
  13.                     public void onErrorResponse(VolleyError volleyError) {  
  14.                         Toast.makeText(MainActivity.this, volleyError.toString(), Toast.LENGTH_LONG).show();  
  15.                     }  
  16.                 });  
  17.         /*请求对象设置Tag标签,并加入全局队列*/  
  18.         request.setTag("JsonGet");  
  19.         MyApplication.getHttpQueues().add(request);  
  20.   
  21.     }</span>  

Post:String方式

这里注意psot方式中URL不直接携带,StringPsot需要使用getParams()设置

[java]  view plain  copy
  1. <span style="font-size:18px;">private void Volley_StringPost() {  
  2.         /*这里使用StringRequets*/  
  3.         String url = "http://ip.taobao.com/service/getIpInfo.php?";  
  4.         StringRequest request = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {  
  5.             @Override  
  6.             public void onResponse(String s) {  
  7.                 Toast.makeText(MainActivity.this, s, Toast.LENGTH_LONG).show();  
  8.   
  9.             }  
  10.         }, new Response.ErrorListener() {  
  11.             @Override  
  12.             public void onErrorResponse(VolleyError volleyError) {  
  13.                 Toast.makeText(MainActivity.this, volleyError.toString(), Toast.LENGTH_LONG).show();  
  14.   
  15.             }  
  16.         }) {  
  17.             @Override  
  18.             protected Map<String, String> getParams() throws AuthFailureError {  
  19.                 //这里需要设置post的参数  
  20.                 Map<String, String> hashMap = new HashMap<String, String>();  
  21.                 hashMap.put("ip""125.71.229.221");  
  22.                 return hashMap;  
  23.             }  
  24.         };  
  25.         //post请求需要单独实现  
  26.         /*请求对象设置Tag标签,并加入全局队列*/  
  27.         request.setTag("StringPost");  
  28.         MyApplication.getHttpQueues().add(request);  
  29.     }</span>  

Post :Json方式

这种方式首先需要HashMap来装参数,然后把新建jsonObj携带该参数即可使用,后来测试时发现这里使用的是淘宝IP查询接口不支持post方式,但是StringPost可以,jsonPost貌似不可以,不过操作方式是对的,你也可以换个其他结口试试。

[java]  view plain  copy
  1. <span style="font-size:18px;"private void Volley_JsonPost() {  
  2.         /*这里使用JsonRequets*/  
  3.         String url = "http://ip.taobao.com/service/getIpInfo.php?";  
  4.   
  5.         HashMap<String, String> hashMap = new HashMap<String, String>();  
  6.         hashMap.put("ip""125.71.229.222");  
  7.         JSONObject jsonParams = new JSONObject(hashMap);  
  8.   
  9.         JsonObjectRequest request = new JsonObjectRequest(Request.Method.POST, url, jsonParams, new Response.Listener<JSONObject>() {  
  10.             @Override  
  11.             public void onResponse(JSONObject jsonObject) {  
  12.                 Toast.makeText(MainActivity.this, jsonObject.toString(), Toast.LENGTH_LONG).show();  
  13.             }  
  14.         }, new Response.ErrorListener() {  
  15.             @Override  
  16.             public void onErrorResponse(VolleyError volleyError) {  
  17.                 Toast.makeText(MainActivity.this, volleyError.toString(), Toast.LENGTH_LONG).show();  
  18.             }  
  19.         }) {  
  20.   
  21.             @Override  
  22.             public Map<String, String> getHeaders() {  
  23.                 HashMap<String, String> headers = new HashMap<String, String>();  
  24.                 headers.put("Accept""application/json");  
  25.                 headers.put("Content-Type""application/json; charset=UTF-8");  
  26.                 return headers;  
  27.             }  
  28.         };  
  29.         /*请求对象设置Tag标签,并加入全局队列*/  
  30.         request.setTag("JsonPost");  
  31.         MyApplication.getHttpQueues().add(request);  
  32.     }</span>  


Volley与Activity进行联动:

当Activity进行关闭的时候需要在onStop方法处理,yourTag则是你设置关联的Tag

[java]  view plain  copy
  1. <span style="font-size:18px;"@Override  
  2.     protected void onStop() {  
  3.         super.onStop();  
  4.         MyApplication.getHttpQueues().cancelAll("yourTag");  
  5.     }</span>  

Volley的简单的二次封装我们将它写在utils包中

不如我们在请求失败都要加一个toast弹窗或者请求成功加一些其他的提示,需要在每次使用的地方都加上,比较麻烦,我们可以做一个二次封装以便全局统一使用

主要封装请求成功和请求失败的回调,这里以StringRequest为例

首先需要一个接口Interface

[java]  view plain  copy
  1. <span style="font-size:18px;">public abstract class VolleyStringReqItf {  
  2.     public Context context;  
  3.     public static Response.Listener<String> listener;  
  4.     public static Response.ErrorListener errorListener;  
  5.   
  6.     //成功和失败的回调函数  
  7.     public abstract void onMySuccess(String result);  
  8.   
  9.     public abstract void onMyError(VolleyError error);  
  10.   
  11.     public VolleyStringReqItf(Context context, Response.Listener<String> listener, Response.ErrorListener errorListener) {  
  12.         this.context = context;  
  13.         this.listener = listener;  
  14.         this.errorListener = errorListener;  
  15.     }  
  16.   
  17.     public Response.Listener<String> loadingListener() {  
  18.         listener = new Response.Listener<String>() {  
  19.             @Override  
  20.             public void onResponse(String response) {  
  21.                 onMySuccess(response);  
  22.             }  
  23.         };  
  24.         return listener;  
  25.     }  
  26.   
  27.     public Response.ErrorListener errorListener() {  
  28.         errorListener = new Response.ErrorListener() {  
  29.             @Override  
  30.             public void onErrorResponse(VolleyError volleyError) {  
  31.                 onMyError(volleyError);  
  32.             }  
  33.         };  
  34.         return errorListener;  
  35.     }  
  36. }  
  37. </span>  

然后是我们自定义的StringRequest,注释很详细
[java]  view plain  copy
  1. <span style="font-size:18px;">/** 
  2.  * Created by ELVIS on 2015/11/7. 
  3.  */  
  4. public class VolleyStrRequest {  
  5.     public static StringRequest stringRequest;  
  6.     public static Context context;  
  7.   
  8.     public static void RequestStrGet(Context context, String url, String tag, VolleyStringReqItf vif) {  
  9.         //取消当前tag的volley请求防止重复请求  
  10.         MyApplication.getHttpQueues().cancelAll(tag);  
  11.   
  12.         stringRequest = new StringRequest(Request.Method.GET, url, vif.loadingListener(), vif.errorListener());  
  13.         stringRequest.setTag(tag);  
  14.         MyApplication.getHttpQueues().add(stringRequest);  
  15.         //开启请求  
  16.         MyApplication.getHttpQueues().start();  
  17.   
  18.     }  
  19.   
  20.     public static void ReqestStrPost(Context context, String url, String tag, final HashMap<String, String> params, VolleyStringReqItf vif) {  
  21.         MyApplication.getHttpQueues().cancelAll(tag);  
  22.   
  23.         stringRequest = new StringRequest(Request.Method.POST, url, vif.loadingListener(), vif.errorListener()) {  
  24.             @Override  
  25.             protected Map<String, String> getParams() throws AuthFailureError {  
  26.                 return params;  
  27.             }  
  28.         };  
  29.         stringRequest.setTag(tag);  
  30.         MyApplication.getHttpQueues().add(stringRequest);  
  31.         MyApplication.getHttpQueues().start();  
  32.     }  
  33. }  
  34. </span>  

这样使用起来就比较方便了,当然你也可以自定义自己的其他的VolleyRequest

3、Volley框架使用之加载图片的用法

【缓存功能简单介绍】

图片加载缓存主要使用了LruCache和ImageCache

【加载网络图片及监听】

主要是NetworkImageView

3.1、使用ImageRequest来请求网络图片

ImageRequest能够处理单张图片,返回bitmap。ImageReques通常有5个参数(url,成功listtener,加载图片宽度设置,加载图片高度设置,bitmap配置,失败listener),当加载图片宽高都为0表示按照原图大小加载

[java]  view plain  copy
  1. <span style="font-size:18px;"private void initView() {  
  2.         iv_img = (ImageView) findViewById(R.id.iv_img);  
  3.         String url = " http://h.hiphotos.baidu.com/image/pic/item/d53f8794a4c27d1e3584e91b1fd5ad6edcc4384b.jpg";  
  4.         ImageRequest request = new ImageRequest(url, new Response.Listener<Bitmap>() {  
  5.             @Override  
  6.             public void onResponse(Bitmap bitmap) {  
  7.                 iv_img.setImageBitmap(bitmap);  
  8.   
  9.             }  
  10.         }, 00, Bitmap.Config.RGB_565, new Response.ErrorListener() {  
  11.             @Override  
  12.             public void onErrorResponse(VolleyError volleyError) {  
  13.                 Toast.makeText(ImageActivity.this"Failure", Toast.LENGTH_SHORT).show();  
  14.             }  
  15.         });  
  16.         MyApplication.getHttpQueues().add(request);  
  17.     }</span>  

3.2、使用ImageLoader

    ImageLoader这个类需要一个Request的实例以及一个ImageCache的实例。图片通过一个URL和一个ImageListener实例的get()方法就可以被加载。ImageLoader会检查ImageCache,而且如果缓存里没有图片就会从网络上获取。
    Volley的ImageCache接口允许你使用你喜欢的Lru缓存实现。不幸的是Volley没有提供默认的实现。我们需要自己实现一个Bitcache
    ImageCache接口有两个方法,getBitmap(String url)和putBitmap(String url, Bitmap bitmap).这两个方法足够简单直白,他们可以添加任何的缓存实现。

BItMapCache.Java

[java]  view plain  copy
  1. <span style="font-size:18px;">public class BitmapCache implements ImageLoader.ImageCache {  
  2.   
  3.     public LruCache<String, Bitmap> cache;  
  4.     public static final int MAX = 5 * 1024 * 1024;  
  5.   
  6.     public BitmapCache() {  
  7.         cache = new LruCache<String, Bitmap>(MAX) {  
  8.             @Override  
  9.             protected int sizeOf(String key, Bitmap value) {  
  10.                 return value.getRowBytes() * value.getHeight();  
  11.             }  
  12.         };  
  13.     }  
  14.   
  15.     @Override  
  16.     public Bitmap getBitmap(String s) {  
  17.         return cache.get(s);  
  18.     }  
  19.   
  20.     @Override  
  21.     public void putBitmap(String s, Bitmap bitmap) {  
  22.         cache.put(s, bitmap);  
  23.     }  
  24. }  
  25. </span>  

使用   ImageLoader,其中getImgListner

        // imageView是一个ImageView实例  
        // ImageLoader.getImageListener的第二个参数是默认的图片resource id  
        // 第三个参数是请求失败时候的资源id,可以指定为0 

[java]  view plain  copy
  1. <span style="font-size:18px;">private void initViewImgLoader() {  
  2.         Toast.makeText(ImageActivity.this"ImgLoader方式", Toast.LENGTH_SHORT).show();  
  3.         String url = "http://image.tianjimedia.com/uploadImages/2012/090/063N2L5N2HID.jpg";  
  4.         //ImageLoader  
  5.         ImageLoader loader = new ImageLoader(MyApplication.getHttpQueues(), new BitmapCache());  
  6.         ImageLoader.ImageListener listener = ImageLoader.getImageListener(iv_img, R.mipmap.ic_launcher, R.mipmap.ic_launcher);  
  7.         loader.get(url, listener);  
  8.     }</span>  

3.3、使用NetworkImageView方式

NetworkImageView 继承了 ImageView,并且在内部添加了

 

[java]  view plain  copy
  1. <span style="font-size:18px;">    public void setImageUrl(String url, ImageLoader imageLoader) {}  </span>  

这里可以看出,使用NetworkImageView时候我们需要跟ImageLoader配合使用,而且还多了加载前默认图片和加载失败图片的方法

[java]  view plain  copy
  1. <span style="font-size:18px;">public void setDefaultImageResId(int defaultImage) {    
  2. mDefaultImageId = defaultImage;    
  3. }    
  4. /**  
  5. * Sets the error image resource ID to be used for this view in the event that the image  
  6. * requested fails to load.  
  7. */    
  8. public void setErrorImageResId(int errorImage) {    
  9. mErrorImageId = errorImage;    
  10. } </span>  

使用代码:

[java]  view plain  copy
  1. <span style="font-size:18px;">private void initViewNetWorkImg() {  
  2.         Toast.makeText(ImageActivity.this"NetWorkImg方式", Toast.LENGTH_SHORT).show();  
  3.         netImgView = (NetworkImageView) findViewById(R.id.netWorkImg);  
  4.         String url = "http://new.aliyiyao.com/UpFiles/Image/2011/01/13/nc_129393721364387442.jpg";  
  5.         ImageLoader loader = new ImageLoader(MyApplication.getHttpQueues(), new BitmapCache());  
  6.         netImgView.setDefaultImageResId(R.mipmap.ic_launcher);  
  7.         netImgView.setErrorImageResId(R.mipmap.ic_launcher);  
  8.         netImgView.setImageUrl(url, loader);  
  9.   
  10.     }</span>  

demo地址http://download.csdn.net/detail/xsf50717/9251751


转自:http://blog.csdn.net/xsf50717/article/details/49687015

目录
相关文章
|
10月前
Volley源码分析(一)
Volley源码分析(一)
131 0
|
JSON 数据格式
Volley使用原理笔记
Volley使用原理笔记
关于volley的使用
https://blog.csdn.net/qwm8777411/article/details/45770979
692 0
|
缓存
Volley源码解析
Volley是一款轻量级的网络访问框架,适合小批量的数据传输。Volley的使用通过newRequestQueue创建一个RequestQueue对象,并调用RequestQueue.add方法来提交任务。
1039 0
|
Android开发 数据格式 XML
volley框架使用小Demo
MainActivity public class MainActivity extends AppCompatActivity { private static final String URL = "https://www.
952 0
|
JSON Java Android开发