一、Volley概述
- Volley 是Android上的一个网络通信库,能使网络通信更简单健壮。
- Volley 适合数据量不大但通信比较频繁的场景。
二、相关的API
RequestQueue:请求队列,会自动执行队列中的请求
Volley.newRequestQueue(context):创建一个请求队列
addRequest(Request request):将请求添加到队列中处理
Request:请求的接口
StringRequest:获取字符串数据的网络请求
JsonRequest:获取JSON数据的网络请求
ImageRequest:获取图片结果的网络请求
三、使用Volley进行GET网络请求
一、StringRequest示例
RequestQueue requestQueue ;
private String path = "http://apis.baidu.com/apistore/idservice/id=11111";
//获取请求队列实例
requestQueue = Volley.newRequestQueue(this);
StringRequest stringRequest = new StringRequest(Request.Method.POST, path, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
//在主线程中进行返回数据处理
Toast.makeText(MainActivity.this,response,Toast.LENGTH_SHORT).show();
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
//在主线程中运行TODO
Toast.makeText(MainActivity.this,error.toString(),Toast.LENGTH_SHORT).show();
}
});
// 加入队列
requestQueue.add(stringRequest);
三、使用Volley进行POST网络请求
一、StringRequest示例
RequestQueue requestQueue ;
private String path = "http://apis.baidu.com/apistore/weatherservice/citylist";
requestQueue = Volley.newRequestQueue(this);
StringRequest stringRequest = new StringRequest(Request.Method.POST, path, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
//在主线程中运行
Toast.makeText(MainActivity.this,response,Toast.LENGTH_SHORT).show();
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
//在主线程中运行TODO
Toast.makeText(MainActivity.this,error.toString(),Toast.LENGTH_SHORT).show();
}
}){
@Override
protected Map<String, String> getParams() throws AuthFailureError {
//设置提交请求的参数
Map<String, String> params = new HashMap<String, String>();
params.put("city","%E6%9C%9D%E9%98%B3");
return params;
}
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
//设置提交请求的头部信息
return super.getHeaders();
}
};
// 加入队列
requestQueue.add(stringRequest);
二、JsonObjectRequest示例
注:JsonObjectRequest 不能重写 getParams 来传参
RequestQueue requestQueue ; private String path = "http://apis.baidu.com/apistore/weatherservice/citylist"; //获取请求队列实例 requestQueue = Volley.newRequestQueue(this); //设置请求参数 String params = "city=%E6%9C%9D%E9%98%B3"; //在构造方法中传参,不能通过getParams来传参 JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, path, params, new Response.Listener<JSONObject>() { @Override public void onResponse(JSONObject response) { Toast.makeText(MainActivity.this,response.toString(),Toast.LENGTH_SHORT).show(); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Toast.makeText(MainActivity.this,error.toString(),Toast.LENGTH_SHORT).show(); } }); requestQueue.add(jsonObjectRequest);
四、使用Volley来加载图片
一、使用ImageRequest获取图片bitmap
RequestQueue requestQueue ;
//获取请求队列实例
requestQueue = Volley.newRequestQueue(this);
//图片地址
String url = "http://avatar.csdn.net/6/9/1/1_cxmscb.jpg";
/*
* ImageRequest的构造方法的参数说明:
* 第一个参数:图片url,第二个参数:响应监听器
* 第三个参数、第四个参数:分别用于指定允许图片最大的宽度和高度.
* 如果指定的网络图片的宽度或高度大于这里的最大值,则会对图片进行压缩.
* 指定为0的话就表示不管图片有多大,都不会进行压缩。
* 第五个参数:scaletype.图片的填充方式
* 第六个参数:指定图片的颜色属性.
* ARGB_8888可展示最好的颜色属性,每个图片像素占据4个字节的大小.
* RGB_565则表示每个图片像素占据2个字节大小
* 第七个参数:请求失败后的回调
*
*/
ImageRequest imageRequest = new ImageRequest(url, new Response.Listener<Bitmap>() {
@Override
public void onResponse(Bitmap response) {
Toast.makeText(MainActivity.this,"success",Toast.LENGTH_SHORT).show();
((ImageView)MainActivity.this.findViewById(R.id.imageView)).setImageBitmap(response);
}
}, 200, 200, ImageView.ScaleType.CENTER, Bitmap.Config.ARGB_8888, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(MainActivity.this,error.toString(),Toast.LENGTH_SHORT).show();
}
});
requestQueue.add(imageRequest);
二、使用ImageLoader加载图片
ImageLoader的内部是使用ImageRequest来实现的,不过ImageLoader要比ImageRequest更加高效,它不仅可以对图片缓存ImageCache,还可以过滤掉重复的链接,避免重复发送请求。
RequestQueue requestQueue ; //获取请求队列实例 requestQueue = Volley.newRequestQueue(this); ImageView imageView = (ImageView) findViewById(R.id.imageView); String url = "http://avatar.csdn.net/6/9/1/1_cxmscb.jpg"; /* 第一个参数:RequestQueue对象。 * 第二个参数是一个ImageCache对象。 * BitmapCache为ImageCache子类,起到图片缓存的作用 */ ImageLoader imageLoader = new ImageLoader(requestQueue,new BitmapCache()); /* 第一个参数:显示图片的ImageView控件. * 第二个参数:加载图片时显示的图片. */ 第三个参数:加载图片失败时显示的图片。 ImageLoader.ImageListener imageListener = ImageLoader.getImageListener(imageView,R.drawable.default_img,R.drawable.error_img); //第三个参数、第四个参数:分别用于指定允许图片最大的宽度和高度. imageLoader.get(url,imageListener,200,200);
public class BitmapCache implements ImageLoader.ImageCache {
private LruCache<String, Bitmap> mCache;
public BitmapCache() {
int maxSize = 10 * 1024 * 1024;
//将缓存图片的总大小设置为10M
mCache = new LruCache<String, Bitmap>(maxSize) {
@Override
protected int sizeOf(String key, Bitmap bitmap) {
return bitmap.getRowBytes() * bitmap.getHeight();
}
};
}
@Override
public Bitmap getBitmap(String url) {
return mCache.get(url);
}
@Override
public void putBitmap(String url, Bitmap bitmap) {
mCache.put(url, bitmap);
}
}
三、使用NetworkImageView来加载图片
NetworkImageView是一个自定义控件,继承自ImageView,在ImageVie的基础之上加入了加载网络图片的功能。
<com.android.volley.toolbox.NetworkImageView android:layout_width="220dp" android:layout_height="220dp" android:id="@+id/imageView" android:scaleType="centerInside" />
NetworkImageView在加载图片时,会自动获取自身的宽高,然后与网络图片的宽高对比,再决定是否需要对图片进行压缩。
当不想对图片进行压缩,可在布局文件中把NetworkImageView的属性layout_width和layout_height设置成wrap_content.NetworkImageView networkImageView = (NetworkImageView) findViewById(R.id.networkImageView); networkImageView.setDefaultImageResId(R.drawable.default_img); networkImageView.setErrorImageResId(R.drawable.error_img); String url = "http://avatar.csdn.net/6/9/1/1_cxmscb.jpg"; ImageLoader imageLoader = new ImageLoader(requestQueue,new BitmapCache()); networkImageView.setImageUrl(url,imageLoader);
NetworkImageView控件的用法要比前两种方式更加简单,不需要再创建一个ImageListener。
五、request请求的取消
如果在Activity里启动了volley网络请求,那么在Activity销毁之前应将还没完成的请求/未启动的请求进行取消以释放内存资源。
public static final String TAG = "MyTag";
StringRequest stringRequest; // Assume this exists.
RequestQueue mRequestQueue; // Assume this exists.
//给请求设置标记
stringRequest.setTag(TAG);
...
...
@Override
protected void onStop () {
super.onStop();
if (mRequestQueue != null) {
mRequestQueue.cancelAll(TAG);
}
}