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中
- <span style="font-size:18px;">public class MyApplication extends Application {
-
- public static RequestQueue queues;
- @Override
- public void onCreate() {
- super.onCreate();
- queues = Volley.newRequestQueue(getApplicationContext());
- }
-
- public static RequestQueue getHttpQueues(){
- return queues;
- }
- }</span>
然后在MAinActivity中给出StringResponse的方式,这里主要有四个参数 请求方式,url,请求成功回调函数,请求失败回调函数
Get方式URL直接携带参数
Get:String方式
- <span style="font-size:18px;">private void Volley_StringGet() {
-
- String url = "http://ip.taobao.com/service/getIpInfo.php?ip=125.71.229.221";
- StringRequest request = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
- @Override
- public void onResponse(String s) {
- Toast.makeText(MainActivity.this, s, Toast.LENGTH_LONG).show();
-
- }
- }, new Response.ErrorListener() {
- @Override
- public void onErrorResponse(VolleyError volleyError) {
- Toast.makeText(MainActivity.this, volleyError.toString(), Toast.LENGTH_LONG).show();
-
- }
- });
-
- request.setTag("StringGet");
- MyApplication.getHttpQueues().add(request);
-
- }</span>
Get:Json方式
- <span style="font-size:18px;">private void Volley_JsonGet() {
-
- String url = "http://ip.taobao.com/service/getIpInfo.php?ip=125.71.229.221";
- JsonObjectRequest request = new JsonObjectRequest(Request.Method.POST, url, null, new Response.Listener<JSONObject>() {
- @Override
- public void onResponse(JSONObject js) {
- Toast.makeText(MainActivity.this, js.toString(), Toast.LENGTH_LONG).show();
-
- }
- },
- new Response.ErrorListener() {
- @Override
- public void onErrorResponse(VolleyError volleyError) {
- Toast.makeText(MainActivity.this, volleyError.toString(), Toast.LENGTH_LONG).show();
- }
- });
-
- request.setTag("JsonGet");
- MyApplication.getHttpQueues().add(request);
-
- }</span>
Post:String方式
这里注意psot方式中URL不直接携带,StringPsot需要使用getParams()设置
- <span style="font-size:18px;">private void Volley_StringPost() {
-
- String url = "http://ip.taobao.com/service/getIpInfo.php?";
- StringRequest request = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
- @Override
- public void onResponse(String s) {
- Toast.makeText(MainActivity.this, s, Toast.LENGTH_LONG).show();
-
- }
- }, new Response.ErrorListener() {
- @Override
- public void onErrorResponse(VolleyError volleyError) {
- Toast.makeText(MainActivity.this, volleyError.toString(), Toast.LENGTH_LONG).show();
-
- }
- }) {
- @Override
- protected Map<String, String> getParams() throws AuthFailureError {
-
- Map<String, String> hashMap = new HashMap<String, String>();
- hashMap.put("ip", "125.71.229.221");
- return hashMap;
- }
- };
-
-
- request.setTag("StringPost");
- MyApplication.getHttpQueues().add(request);
- }</span>
Post :Json方式
这种方式首先需要HashMap来装参数,然后把新建jsonObj携带该参数即可使用,后来测试时发现这里使用的是淘宝IP查询接口不支持post方式,但是StringPost可以,jsonPost貌似不可以,不过操作方式是对的,你也可以换个其他结口试试。
- <span style="font-size:18px;"> private void Volley_JsonPost() {
-
- String url = "http://ip.taobao.com/service/getIpInfo.php?";
-
- HashMap<String, String> hashMap = new HashMap<String, String>();
- hashMap.put("ip", "125.71.229.222");
- JSONObject jsonParams = new JSONObject(hashMap);
-
- JsonObjectRequest request = new JsonObjectRequest(Request.Method.POST, url, jsonParams, new Response.Listener<JSONObject>() {
- @Override
- public void onResponse(JSONObject jsonObject) {
- Toast.makeText(MainActivity.this, jsonObject.toString(), Toast.LENGTH_LONG).show();
- }
- }, new Response.ErrorListener() {
- @Override
- public void onErrorResponse(VolleyError volleyError) {
- Toast.makeText(MainActivity.this, volleyError.toString(), Toast.LENGTH_LONG).show();
- }
- }) {
-
- @Override
- public Map<String, String> getHeaders() {
- HashMap<String, String> headers = new HashMap<String, String>();
- headers.put("Accept", "application/json");
- headers.put("Content-Type", "application/json; charset=UTF-8");
- return headers;
- }
- };
-
- request.setTag("JsonPost");
- MyApplication.getHttpQueues().add(request);
- }</span>
Volley与Activity进行联动:
当Activity进行关闭的时候需要在onStop方法处理,yourTag则是你设置关联的Tag
- <span style="font-size:18px;"> @Override
- protected void onStop() {
- super.onStop();
- MyApplication.getHttpQueues().cancelAll("yourTag");
- }</span>
Volley的简单的二次封装我们将它写在utils包中
不如我们在请求失败都要加一个toast弹窗或者请求成功加一些其他的提示,需要在每次使用的地方都加上,比较麻烦,我们可以做一个二次封装以便全局统一使用
主要封装请求成功和请求失败的回调,这里以StringRequest为例
首先需要一个接口Interface
- <span style="font-size:18px;">public abstract class VolleyStringReqItf {
- public Context context;
- public static Response.Listener<String> listener;
- public static Response.ErrorListener errorListener;
-
-
- public abstract void onMySuccess(String result);
-
- public abstract void onMyError(VolleyError error);
-
- public VolleyStringReqItf(Context context, Response.Listener<String> listener, Response.ErrorListener errorListener) {
- this.context = context;
- this.listener = listener;
- this.errorListener = errorListener;
- }
-
- public Response.Listener<String> loadingListener() {
- listener = new Response.Listener<String>() {
- @Override
- public void onResponse(String response) {
- onMySuccess(response);
- }
- };
- return listener;
- }
-
- public Response.ErrorListener errorListener() {
- errorListener = new Response.ErrorListener() {
- @Override
- public void onErrorResponse(VolleyError volleyError) {
- onMyError(volleyError);
- }
- };
- return errorListener;
- }
- }
- </span>
然后是我们自定义的StringRequest,注释很详细
- <span style="font-size:18px;">
-
-
- public class VolleyStrRequest {
- public static StringRequest stringRequest;
- public static Context context;
-
- public static void RequestStrGet(Context context, String url, String tag, VolleyStringReqItf vif) {
-
- MyApplication.getHttpQueues().cancelAll(tag);
-
- stringRequest = new StringRequest(Request.Method.GET, url, vif.loadingListener(), vif.errorListener());
- stringRequest.setTag(tag);
- MyApplication.getHttpQueues().add(stringRequest);
-
- MyApplication.getHttpQueues().start();
-
- }
-
- public static void ReqestStrPost(Context context, String url, String tag, final HashMap<String, String> params, VolleyStringReqItf vif) {
- MyApplication.getHttpQueues().cancelAll(tag);
-
- stringRequest = new StringRequest(Request.Method.POST, url, vif.loadingListener(), vif.errorListener()) {
- @Override
- protected Map<String, String> getParams() throws AuthFailureError {
- return params;
- }
- };
- stringRequest.setTag(tag);
- MyApplication.getHttpQueues().add(stringRequest);
- MyApplication.getHttpQueues().start();
- }
- }
- </span>
这样使用起来就比较方便了,当然你也可以自定义自己的其他的VolleyRequest
3、Volley框架使用之加载图片的用法
【缓存功能简单介绍】
图片加载缓存主要使用了LruCache和ImageCache
【加载网络图片及监听】
主要是NetworkImageView
3.1、使用ImageRequest来请求网络图片
ImageRequest能够处理单张图片,返回bitmap。ImageReques通常有5个参数(url,成功listtener,加载图片宽度设置,加载图片高度设置,bitmap配置,失败listener),当加载图片宽高都为0表示按照原图大小加载
- <span style="font-size:18px;"> private void initView() {
- iv_img = (ImageView) findViewById(R.id.iv_img);
- String url = " http://h.hiphotos.baidu.com/image/pic/item/d53f8794a4c27d1e3584e91b1fd5ad6edcc4384b.jpg";
- ImageRequest request = new ImageRequest(url, new Response.Listener<Bitmap>() {
- @Override
- public void onResponse(Bitmap bitmap) {
- iv_img.setImageBitmap(bitmap);
-
- }
- }, 0, 0, Bitmap.Config.RGB_565, new Response.ErrorListener() {
- @Override
- public void onErrorResponse(VolleyError volleyError) {
- Toast.makeText(ImageActivity.this, "Failure", Toast.LENGTH_SHORT).show();
- }
- });
- MyApplication.getHttpQueues().add(request);
- }</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
- <span style="font-size:18px;">public class BitmapCache implements ImageLoader.ImageCache {
-
- public LruCache<String, Bitmap> cache;
- public static final int MAX = 5 * 1024 * 1024;
-
- public BitmapCache() {
- cache = new LruCache<String, Bitmap>(MAX) {
- @Override
- protected int sizeOf(String key, Bitmap value) {
- return value.getRowBytes() * value.getHeight();
- }
- };
- }
-
- @Override
- public Bitmap getBitmap(String s) {
- return cache.get(s);
- }
-
- @Override
- public void putBitmap(String s, Bitmap bitmap) {
- cache.put(s, bitmap);
- }
- }
- </span>
使用 ImageLoader,其中getImgListner
// imageView是一个ImageView实例
// ImageLoader.getImageListener的第二个参数是默认的图片resource id
// 第三个参数是请求失败时候的资源id,可以指定为0
- <span style="font-size:18px;">private void initViewImgLoader() {
- Toast.makeText(ImageActivity.this, "ImgLoader方式", Toast.LENGTH_SHORT).show();
- String url = "http://image.tianjimedia.com/uploadImages/2012/090/063N2L5N2HID.jpg";
-
- ImageLoader loader = new ImageLoader(MyApplication.getHttpQueues(), new BitmapCache());
- ImageLoader.ImageListener listener = ImageLoader.getImageListener(iv_img, R.mipmap.ic_launcher, R.mipmap.ic_launcher);
- loader.get(url, listener);
- }</span>
3.3、使用NetworkImageView方式
NetworkImageView 继承了 ImageView,并且在内部添加了
- <span style="font-size:18px;"> public void setImageUrl(String url, ImageLoader imageLoader) {} </span>
这里可以看出,使用NetworkImageView时候我们需要跟ImageLoader配合使用,而且还多了加载前默认图片和加载失败图片的方法
- <span style="font-size:18px;">public void setDefaultImageResId(int defaultImage) {
- mDefaultImageId = defaultImage;
- }
-
-
-
-
- public void setErrorImageResId(int errorImage) {
- mErrorImageId = errorImage;
- } </span>
使用代码:
- <span style="font-size:18px;">private void initViewNetWorkImg() {
- Toast.makeText(ImageActivity.this, "NetWorkImg方式", Toast.LENGTH_SHORT).show();
- netImgView = (NetworkImageView) findViewById(R.id.netWorkImg);
- String url = "http://new.aliyiyao.com/UpFiles/Image/2011/01/13/nc_129393721364387442.jpg";
- ImageLoader loader = new ImageLoader(MyApplication.getHttpQueues(), new BitmapCache());
- netImgView.setDefaultImageResId(R.mipmap.ic_launcher);
- netImgView.setErrorImageResId(R.mipmap.ic_launcher);
- netImgView.setImageUrl(url, loader);
-
- }</span>
demo地址http://download.csdn.net/detail/xsf50717/9251751
转自:http://blog.csdn.net/xsf50717/article/details/49687015