您的位置:首页 > 移动开发 > Android开发

Volley学习小结

2015-11-08 11:27 369 查看

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() {
/*这里使用StringRequets*/
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();

}
});
/*请求对象设置Tag标签,并加入全局队列*/
request.setTag("StringGet");
MyApplication.getHttpQueues().add(request);

}</span>
Get:Json方式
<span style="font-size:18px;">private void Volley_JsonGet() {
/*这里使用JsonRequets*/
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();
}
});
/*请求对象设置Tag标签,并加入全局队列*/
request.setTag("JsonGet");
MyApplication.getHttpQueues().add(request);

}</span>


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

<span style="font-size:18px;">private void Volley_StringPost() {
/*这里使用StringRequets*/
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 {
//这里需要设置post的参数
Map<String, String> hashMap = new HashMap<String, String>();
hashMap.put("ip", "125.71.229.221");
return hashMap;
}
};
//post请求需要单独实现
/*请求对象设置Tag标签,并加入全局队列*/
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() {
/*这里使用JsonRequets*/
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;
}
};
/*请求对象设置Tag标签,并加入全局队列*/
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;">/**
* Created by ELVIS on 2015/11/7.
*/
public class VolleyStrRequest {
public static StringRequest stringRequest;
public static Context context;

public static void RequestStrGet(Context context, String url, String tag, VolleyStringReqItf vif) {
//取消当前tag的volley请求防止重复请求
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
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;
}
/**
* Sets the error image resource ID to be used for this view in the event that the image
* requested fails to load.
*/
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android volley