一、Volley提供的功能
Volley特别适合数据量不大但是通信频繁的场景。
Volley应该是简化了网络通信的一些开发,特别是针对如下两种情况:
- JSON对象
- 图片加载
简单来说,它提供了如下的便利功能:
- JSON,图像等的异步下载;
- 网络请求的排序(scheduling)
- 网络请求的优先级处理
- 缓存
- 多级别取消请求
- 和Activity和生命周期的联动(Activity结束时同时取消所有网络请求)
二、Volley的局限性
Volley不适用大数据(large payloads ),流媒体,这些case,还需要使用原始的方法,比如Download Manager等。
从volley自身的结构来讲,他有两个队列来处理request,首先 一个本地存储队列来获取最新的请求,当
本地存储队列发现有满足这个请求的数据时就返回相应数据,如果没有,则丢到另一个
实现网络请求的队列中去,volley开启了4个线程来读取这个队列,保证队列中网络请求停留极短的时间。每个读取线程独自接着实现请求和数据分发
Volley:
文本:StringRequest JsonObjectRequest JsonArrayRequest
图片:ImageRequest ImageLoader NetWorkImageView
Volley使用步骤:
1.新建一个请求队列 RequestQueue
2.实例化请求队列
3.新建一个StringRequest 请求对象,并实例化
4.将请求对象添加到请求队列中
//声明请求队列
RequestQueue requestQueue;
// 实例化请求队列
requestQueue = Volley.newRequestQueue(this);// 单例模式
requestQueue = Volley.newRequestQueue(this);// 单例模式
StringRequest
|
// 实例化一个StringRequest对象
StringRequest stringRequest = new
StringRequest(url, //请求的网址
new Listener<String>() { },//网络访问成功,回调的接口
new ErrorListener() {});//访问网络失败,回调的接口
|
// 实例化一个StringRequest对象
StringRequest stringRequest1 = new StringRequest(
Method.POST,
//请求方式
url,
//请求网址
new Listener<String>() {
//网络访问成功,回调的接口
@Override
public void onResponse(String arg0) {
// TODO Auto-generated method stub
} },
new ErrorListener() {
//
访问网络失败,回调的接口
@Override
public void onErrorResponse(VolleyError arg0) {
}
}) {
//重写StringRequest中的该方法,用于设置Post请求的参数
@Override
protected Map<String, String>
getParams() throws AuthFailureError {
String username = "张三";
String password = "1243";
Map<String, String> params = new HashMap<String, String>();
params.put("username", username);
params.put("password", password);
return params;
}
};
|
JsonObjectRequest
|
/
/ 实例化一个jsonobjectRequest对象
JsonObjectRequest joRequest = new JsonObjectRequest(
url,
// 请求的网址
null,
// 向服务器发送的数据 若请求方式为get 则为null
new Listener<JSONObject>() {
// 成功访问网络时回调的方法
@Override
public void onResponse(JSONObject arg0) {
Log.i("JsonObjectRequest", "==" + arg0);
}
},
new ErrorListener() {
// 访问网络失败回调的方法
@Override
public void onErrorResponse(VolleyError arg0) {
Log.i("ErrorRequest", "==" + arg0.getMessage());
}
});
|
// 声明并实例化jsonobject对象
Map<String, String> map = new HashMap<String, String>(); map.put("username", "张三"); map.put("password", "123"); JSONObject jsonObject = new JSONObject(map); // 实例化一个jsonobjectRequest对象 JsonObjectRequest joRequest = new JsonObjectRequest(
url
,// 请求的网址
jsonObject , // 向服务器发送的数据 若请求方式为get 则为null new Listener<JSONObject>() { // 成功访问网络时回调的方法 @Override public void onResponse(JSONObject arg0) { Log.i("JsonObjectRequest", "==" + arg0); } },
new ErrorListener() {
// 访问网络失败回调的方法
@Override public void onErrorResponse(VolleyError arg0) { Log.i("ErrorRequest", "==" + arg0.getMessage()); } }); |
JsonArrayRequest
|
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(
url,
new Listener<JSONArray>() {
@Override
public void onResponse(JSONArray arg0) {
}
},
new ErrorListener() {
@Override
public void onErrorResponse(VolleyError arg0) {
}
});
|
Post请求得重写jsonArrayRequest中的两个方法,用于设置请求方法和请求体
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(
url,
new Listener<JSONArray>() { },
new ErrorListener() { }) {
@Override
public byte[] getBody() {
try {
String jsonArray = "[{'userName':'张三','pwd':'123'},{'userName':'李四','p wd':'456'}]";
return jsonArray.getBytes("utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}
@Override
public int getMethod() {
return
Method.POST;
}
};
|
ImageRequest
|
|
// 1.实例化请求队列对象
this.requestQueue = Volley.newRequestQueue(this);
// 2.实例化ImageRequest对象
ImageRequest imageRequest = new ImageRequest(
url,/
/ 需要访问的网址
new Listener<Bitmap>() {
// 成功访问网络后回调的接口
@Override
public void onResponse(Bitmap bitmap) {
imageView_main_net.setImageBitmap(bitmap);
} },
100,
// 指定图片的最大宽度
100,
// 指定图片的最大高度
Config.ARGB_8888,
// 指定图片的解码格式
new ErrorListener() {
// 请求错误时的回调接口
@Override
public void onErrorResponse(VolleyError error) {
System.out.println("error=" + error.getMessage());
}
}
);
5个参数
|
ImageLoader
|
//2.实例化ImageLoader对象,没有对缓存进行处理
ImageLoader imageLoader=new ImageLoader(
requestQueue, //请求队列
new ImageCache() { //图片缓存对象
@Override
public void putBitmap(String url, Bitmap bitmap) {
// TODO Auto-generated method stub
}
@Override
public Bitmap getBitmap(String url) {
// TODO Auto-generated method stub
return null;
}
}
);
使用自定义的图片缓存类:
ImageCacheManger.java
SoftReferenceManger.java
|
//1.实例化请求队列对象
this.requestQueue=Volley.newRequestQueue(this);
//2.实例化ImageLoader对象,并对缓存进行处理
ImageLoader imageLoader=new ImageLoader(
requestQueue,
//请求队列
ImageCacheManger.getInstance()
/
/指定一级缓存对象(自定义图片缓存管理类)
);
//
3.调用ImageLoader对象的getImageListener()将回送的图片和指定的控件进行绑定
imageLoader.get(
url,
//请求图片的网址
imageLoader.getImageListener(
imageView_net_img,
//得到的图片赋值给哪个控件
R.drawable.ic_launcher,
//默认情况下显示的图片
android.R.drawable.ic_delete
//访问网络错误时显示的图片
));
|
NetWorkImageView |
|
//1.实例化请求队列对象
this.requestQueue=Volley.newRequestQueue(this);
//设置默认图片
this.imageView_net_img.setDefaultImageResId(R.drawable.ic_launcher);
//设置出错时显示的图片
this.imageView_net_img.setErrorImageResId(android.R.drawable.ic_delete);
//2.设置NetworkImageView访问网络成功后的图片
this.imageView_net_img.
setImageUrl(
url,
//请求的网址
new ImageLoader(
//ImageLoader对象
requestQueue
, //请求队列
ImageCacheManger.getInstance()
//图片缓存对象
));
|
//将请求对象添加到请求队列中
this.requestQueue.add(joRequest);
图片缓存:一级缓存 二级缓存
单例模式使用步骤:
1.创建一个本类类型的私有静态对象
2.构造方法私有化
3.通过公有的静态方法返回本类类的对象
package com.lm.utils;
import android.graphics.Bitmap;
import android.util.LruCache;
import com.android.volley.toolbox.ImageLoader.ImageCache;
/**
*
自定义一级缓存管理器类
*
* 单例设计模式的使用步骤:
* 1.声明一个私有的静态的本类类型的对象
* 2.构造函数私有化
* 3.通过公有的静态方法返回本类类的对象
* @author dell
*
*/
public class
ImageCacheManger implements ImageCache {
/**
* 1.声明一个私有的静态的本类类型的对象
*/
private static ImageCacheManger instance;
/**
* 声明一级缓存对象
*/
private LruCache<String, Bitmap> lruCache=new LruCache<String, Bitmap>(4*1024*1024){
protected void entryRemoved(boolean evicted, String key, Bitmap oldValue, Bitmap newValue) {
if(evicted){
SoftReferenceManger.getInstance().putBitmap(key, oldValue);
}
}
protected int sizeOf(String key, Bitmap value) {
return value.getRowBytes()*value.getHeight();
//return value.getByteCount();
}
};
/**
* 2.构造函数私有化
*/
private ImageCacheManger(){
}
/**
* 3.通过公有的静态方法返回本类类型对象
* @return
*/
public static ImageCacheManger getInstance(){
if(instance==null){
instance=new ImageCacheManger();
}
return instance;
}
@Override
public Bitmap getBitmap(String url) {
//一级缓存中没有指定url的图片
if(lruCache.get(url)==null){
SoftReferenceManger softReferenceManger= SoftReferenceManger.getInstance();
//说明二级缓存中有指定url的图片
Bitmap bitmap=softReferenceManger.getBitmap(url);
if(bitmap!=null){
lruCache.put(url, bitmap);
softReferenceManger.remove(url);
return bitmap;
}
}
return lruCache.get(url);
}
@Override
public void putBitmap(String url, Bitmap bitmap) {
lruCache.put(url, bitmap);
}
}
|
package com.lm.utils;
import java.lang.ref.SoftReference;
import java.util.HashMap;
import java.util.Map;
import android.graphics.Bitmap;
/**
*
自定义二级缓存类
* @author dell
*
*/
public class
SoftReferenceManger {
/**
* 声明二级缓存存储数据的数据结构对象
*/
private Map<String,SoftReference<Bitmap>> map=new HashMap<String, SoftReference<Bitmap>>();
/**
* 1.声明私有的静态的本类类型的对象
*/
private static SoftReferenceManger instance;
/**
* 2.构造函数私有化
*/
private SoftReferenceManger(){
}
/**
* 3.通过公有的静态方法返回本类类型的对象
* @return
*/
public static SoftReferenceManger getInstance(){
if(instance==null){
instance=new SoftReferenceManger();
}
return instance;
}
/**
* 从二级缓存中取图片时自动调用的方法
* @param url
* @return
*/
public Bitmap getBitmap(String url) {
SoftReference<Bitmap> softReference= map.get(url);
if(softReference!=null){
Bitmap bitmap=softReference.get();
return bitmap;
}
return null;
}
/**
* 将一级缓存中的图片放入二级缓存时自动调用的方法
* @param url
* @param bitmap
*/
public void putBitmap(String url, Bitmap bitmap) {
map.put(url, new SoftReference<Bitmap>(bitmap));
}
/**
* 在从二级缓存中删除指定key的图片时自动调用的方法
* @param url
*/
public void remove(String url) {
map.remove(url);
}
}
|