Volley的中文翻译为“齐射、并发”,是在2013年的Google大会上发布的一款Android平台网络通信库,具有网络请求的处理、小图片的异步加载和缓存等功能,能够帮助 Android APP 更方便地执行网络操作,而且更快速高效。
在Google IO的演讲上,其配图是一幅发射火弓箭的图,有点类似流星。这表示,Volley特别适合数据量不大但是通信频繁的场景。见下图:
而对于大数据量的网络操作,比如说下载文件等,Volley的表现就会非常糟糕。
下图所示的这些应用都是属于数据量不大,但网络通信频繁的,因此非常适合使用Volley。
Volley 的优点:
github地址:
https://github.com/mcxiaoke/android-volley
Eclipse的用户:
下载到github上或者maven上下载Volley的jar包volley.jar,放在libs文件夹内;
Android Studio的用户:
在build.gradle中加入:
compile 'com.mcxiaoke.volley:library:1.0.19'
//1.创建出请求队列
RequestQueue mRequestQueue = Volley.newRequestQueue(this);
//2.创建出来字符串请求对象: StringRequest
/**
* 1param: 请求方式 get/post
* 2p:请求的url地址
* 3p:请求成功后的接口回调
* 4p:请求失败后回调
* 5p:成功的监听,通过参数返回请求到的数据
* 6p:失败的监听,失败在这里处理
*/
StringRequest mStrReq = new StringRequest(Request.Method.GET, "https://www.baidu.com",
new Response.Listener() {
@Override
public void onResponse(String response) {
// 这个方法运行在主线程中,可以直接更新ui
// 通过参数返回请求到的数据
mTv_result.setText(response);
Toast.makeText(StrReqActivity.this, "下载成功", Toast.LENGTH_SHORT).show();
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
// 这个方法运行在主线程中,可以直接更新ui
// 失败在这里处理
Toast.makeText(StrReqActivity.this, "下载失败", Toast.LENGTH_SHORT).show();
}
});
//设置Tag值
mStrReq.setTag("100");
btn_req.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//3.把请求对象添加到请求队列中,会自动发出请求
mRequestQueue.add(mStrReq);
}
});
String url_post = "http://zhushou.72g.com/app/gift/gift_list/";
StringRequest mStrReq = new StringRequest(Request.Method.POST, url_post
, new Response.Listener() {
@Override
public void onResponse(String response) {
//
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
//
}
}) {//这里需要重写getParams方法
@Override
protected Map getParams() throws AuthFailureError {
//把post的请求参数,放入请求体中
//请求条件:platform=2&gifttype=1&compare=60841c5b7c69a1bbb3f06536ed685a48
Map params = new HashMap<>();
params.put("platform", "2");
params.put("gifttype", "1");
params.put("compare", "60841c5b7c69a1bbb3f06536ed685a48");
return params;
}
};
//点击加入到请求队列中
btn_req_json.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mRequestQueue.add(mStrReq);
}
});
附:
Volley支持手动/自动取消请求,可以在Activity销毁的时候手动取消请求:
@Override
protected void onDestroy() {
super.onDestroy();
//取消请求:有三种方式
//1. 取消对应的请求对象
mStrReq.cancel();
//2. 取消请求队列中对应tag的请求
//mRequestQueue.cancelAll("100");
//3. 取消请求队列中所有的请求
//mRequestQueue.cancelAll(this);
}
JsonObjectRequest请求(一样要加到请求队列中才会自动加载)返回的是一个JSONObject对象,创建方法如下:
JsonObjectRequest jsonObjectRequest =new JsonObjectRequest(Request.Method.GET, url, new Response.Listener() {
@Override
public void onResponse(JSONObject response) {
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
});
//1.首先有请求队列
RequestQueue requestQueue = Volley.newRequestQueue(this);
//2.请求对象
//1) 图片下载的url
//2) 下载成功后,返回一个bitmap对象
//3)4) 最大宽度和最大高度,如果超过最大宽度和高度,会进行压缩到你设置的宽度和高度,0不限制
//5) 图片加载的形式
//6)图片显示的质量:RGB_565: 每个像素2字节 ARGB_8888:每个像素占4个字节
//7)下载图片失败后,在这里边处理
ImageRequest imgRequest = new ImageRequest(url_img, new Response.Listener() {
@Override
public void onResponse(Bitmap response) {
//显示成功的图片
iv_show.setImageBitmap(response);
}
}, 0, 0, ImageView.ScaleType.FIT_XY, Bitmap.Config.RGB_565, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
//设置失败的图片
iv_show.setBackgroundResource(R.mipmap.ic_launcher);
}
});
//1、首先有请求队列
RequestQueue requestQueue = Volley.newRequestQueue(this);
//2、创建出ImageLoader对象
ImageLoader loader = new ImageLoader(requestQueue, new BitmapCache());
//3、调用ImageLoader的get方法设置图片
//getImageListener中的三个参数:1,下载好的图片设置给哪个控件 2,默认图片 3.下载失败的图片
loader.get(url_img, ImageLoader.getImageListener(iv_show, R.mipmap.ic_default, R.mipmap.ic_error));
ImageLoader的get的重载方法一览:
public ImageContainer get(String requestUrl, final ImageListener listener) {
return get(requestUrl, listener, 0, 0);
}
public ImageContainer get(String requestUrl, ImageListener imageListener,
int maxWidth, int maxHeight) {
return get(requestUrl, imageListener, maxWidth, maxHeight, ScaleType.CENTER_INSIDE);
}
public ImageContainer get(String requestUrl, ImageListener imageListener,
int maxWidth, int maxHeight, ScaleType scaleType) {
~~~
}
ImageLoader.getImageListener源码一览:
/**
* The default implementation of ImageListener which handles basic functionality
* of showing a default image until the network response is received, at which point
* it will switch to either the actual image or the error image.
* @param view The imageView that the listener is associated with.
* @param defaultImageResId Default image resource ID to use, or 0 if it doesn't exist.
* @param errorImageResId Error image resource ID to use, or 0 if it doesn't exist.
*/
public static ImageListener getImageListener(final ImageView view,
final int defaultImageResId, final int errorImageResId) {
return new ImageListener() {
@Override
public void onErrorResponse(VolleyError error) {
if (errorImageResId != 0) {
view.setImageResource(errorImageResId);
}
}
@Override
public void onResponse(ImageContainer response, boolean isImmediate) {
if (response.getBitmap() != null) {
view.setImageBitmap(response.getBitmap());
} else if (defaultImageResId != 0) {
view.setImageResource(defaultImageResId);
}
}
};
}
这个方法返回一个默认的监听器,来给ImageView设置不同状态下显示的图片。参数defaultImageResId,errorImageResId,可设置0,表示没有默认的图片id和加载错误的图片id。
/**
*缓存bitmap的类
*/
public class BitmapCache implements ImageLoader.ImageCache {
/**
* LruCache最近最少使用的算法 :内存缓存。。。
* 当内存不充足时,会清除最近最少使用的一些图片。
*/
private LruCache mCache;
public BitmapCache() {
//获得到当前应用分配的最大内存
// 一般分1/8内存给图片做缓存用
int maxSize = (int) (Runtime.getRuntime().maxMemory() / 8);
mCache = new LruCache(maxSize) {
@Override
protected int sizeOf(String key, Bitmap value) {
return value.getByteCount(); //返回当前要缓存图片的大小
}
};
}
@Override
public Bitmap getBitmap(String url) {
return mCache.get(url);
}
@Override
public void putBitmap(String url, Bitmap bitmap) {
if (getBitmap(url) == null){ //如果当前缓存中没有url对应的图片,我们再存到内存缓存
mCache.put(url, bitmap);
}
}
}
NetworkImageView拓展了ImageView實現了下載的功能,(相对于使用普通的ImageView,避免由于控件重用带来的图片錯位的问题)。使用方法:
示例如下:
//事先初始化好的RequestQueue和ImageLoader
RequestQueue requestQueue = Volley.newRequestQueue(this);
ImageLoader imageLoader = new ImageLoader(requestQueue, new BitmapCache());
//NetWorkImageView
netiv.setDefaultImageResId(R.mipmap.ic_default); //设置默认的图片的id
netiv.setErrorImageResId(R.mipmap.ic_error); //设置下载失败后的图片的id
netiv.setImageUrl(url_img, imageLoader); //下载图片
對Volley進行再一次的封裝,方便我們的使用:
package com.alex.week06_02.utils;
import android.content.Context;
import android.graphics.Bitmap;
import android.widget.ImageView;
import com.alex.week06_02.BitmapCache;
import com.android.volley.AuthFailureError;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.ImageRequest;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import java.util.Map;
/**
* 單例模式對Volley進行簡單封裝
* @author noonecode
*/
public class VolleyUtils {
private static VolleyUtils mInstance;
private RequestQueue mRequestQueue;
private ImageLoader mImageLoader;
private ImageLoader.ImageCache mCache;
private VolleyUtils(Context context) {
mRequestQueue = Volley.newRequestQueue(context);
mCache = new BitmapCache();
mImageLoader = new ImageLoader(mRequestQueue, mCache);
}
//單例模式
public VolleyUtils newInstance(Context context) {
if (mInstance == null) {
synchronized (VolleyUtils.class) {
if (mInstance == null) {
mInstance = new VolleyUtils(context);
}
}
}
return mInstance;
}
public RequestQueue getRequestQueue() {
return mRequestQueue;
}
public ImageLoader getImageLoader(){
return mImageLoader;
}
/**
* 发送一个字符串请求
* @param method 请求方式GET/POST
* @param url 请求的链接
* @param params POST请求时的参数,可为null
* @param listener 请求返回数据的监听器
* @param errorListener 请求发生错误的监听器
*/
public void sendStringRequest(final int method, String url, final Map params, Response.Listener listener,
Response.ErrorListener errorListener){
StringRequest stringRequest = new StringRequest(method, url, listener, errorListener){
@Override
protected Map getParams() throws AuthFailureError {
if (method == Method.POST) {
return params;
}
return null;
}
};
mRequestQueue.add(stringRequest);
}
/**
* 发送一个字符串请求
* @param url 图片的链接
* @param listener 成功获取到Bitmap的监听器
* @param maxWidth 最大宽度,0则不限制
* @param maxHeight 最大高度,0则不限制
* @param scaleType ImageView的拉伸属性
* @param decodeConfig 图片的格式
* @param errorListener 失败的监听器
*/
public void sendImageRequest(String url, Response.Listener listener, int maxWidth, int maxHeight,
ImageView.ScaleType scaleType, Bitmap.Config decodeConfig, Response.ErrorListener errorListener){
ImageRequest imageRequest = new ImageRequest(url, listener, maxWidth, maxHeight, scaleType, decodeConfig, errorListener);
mRequestQueue.add(imageRequest);
}
}
使用方法:
1. 首先通過單例的方法獲得出VolleyUtils的對象
private VolleyUtils mVolleyUtils;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//~~~
mVolleyUtils = VolleyUtils.newInstance(this);
}
發出一個字符串的請求:
mVolleyUtils.sendStringRequest(Request.Method.GET, "https://www.baidu.com", null, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
tvShow.setText(response);
}
}, null);
發出一個圖片請求:
mVolleyUtils.sendImageRequest("https://www.baidu.com/img/bd_logo1.png", new Response.Listener() {
@Override
public void onResponse(Bitmap response) {
iv_show.setImageBitmap(response);
}
}, 0, 0, ImageView.ScaleType.CENTER, Bitmap.Config.RGB_565, null);
(完畢,如果您(❤ ω ❤)喜歡,請支持點贊)