Volley是Google官方提供的一个用户网络请求的网络框架,有着如下优点:
1,通信更快,编写更加简单。
2,GET,POST请求方式高效异步处理。
3,具有网络请求排序的优先级处理
4,缓存处理
5,多级别消息请求
6,能够和Activity生命周期进行联动
但Volley框架并不适合用来进行上传和下载,因此使用上仍受到一定的限制。
网络请求数据
Volley框架网络请求能返回三种数据类型,通过StringRequest发出请求返回字符串,通过JsonObjectRequest请求返回JsonObject对象,通过JsonArrayRequest发出请求返回JsonArray对象。
使用Volley发出网络请求是自动的,但需要将相应的详细请求添加到消息队列中。我们可以创建一个消息请求队列用于存放相应的消息请求:
RequestQueuequeues = Volley.newRequestQueue(getApplicationContext());
并且通过 queues.add(request);方法将请求添加到消息队列中。
网络请求方式分GET和POST两种,对于Volley网络框架来说,由于GET请求方式是将请求参数写入到url中,所以GET请求方式对于三种请求类型并无不同。对于POST请求方式,则有一定的区别。
1,如果使用StringRequest的请求,则需要在new StringRequest(请求方式,url,Listener,ErrorListener){getParams()}中重写getParams()方法,并返回带有参数的HashMap。当消息队列发出网络请求时将会自动获取该HashMap。以下为代码示例:
String url = "http://apis.juhe.cn/mobile/get?";
StringRequest request = new StringRequest(Request.Method.POST, url, new Response.Listener() {
@Override
public void onResponse(String s) {
Toast.makeText(MainActivity.this, s, Toast.LENGTH_SHORT).show();
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError volleyError) {
Toast.makeText(MainActivity.this, volleyError.toString(), Toast.LENGTH_SHORT).show();
}
}){
@Override
protected Map getParams() throws AuthFailureError {
Map hashMap = new HashMap();
hashMap.put("phone", "13590124703");
hashMap.put("key", "335adcc4e891ba4e4be6d7534fd54c5d");
return hashMap;
}
};
request.setTag("adcPost");
MyApplication.getHttpQueues().add(request);
2,如果使用JsonObjectRequest发出网络请求,则需要在JsonObjectRequest request = new JsonObjectRequest(请求方式,url,JsonObject,Listener,ErrorListener)中加入JsonObject对象。该JsonObject对象是由带参数的HashMap转换而来的。同样将该请求加入消息队列中即可。
Volley与Activity生命周期的联动,只要在Activity中设置取消相应的消息请求即可queue.cancelAll(TAG);
接下来利用cancelAll()方法优化一下网络请求,完成二次请求网络。当程序发出一次网络请求后没收到结果,则可以在消息请求处均设置TAG标识位,每次发送请求均使用cancelALL(TAG)清除掉TAG标识位的网络请求,然后再重新发送请求,避免多次发送无用请求。
同时可以使用回调方法完善网络请求, 看如下代码请求new StringRequest(Request.Method.GET, url, Listener, ErrorListener);,new一个网络请求需要两个监听器,前者是成功请求后的回调接口,后者是失败请求后的回调接口,我们可以通过创建一个抽象类或接口,通过方法给他返回一个监听器。代码如下:
public abstract class VolleyInterface {
public Context mContext;
public static Listener mListener;
public static ErrorListener mErrorListener;
public VolleyInterface(Context context, Listener listener, ErrorListener errorListener){
this.mContext = context;
this.mErrorListener = errorListener;
this.mListener = listener;
}
public abstract void onMySuccess(String result);
public abstract void onMyError(VolleyError error);
public Listener loadingListener(){
mListener = new Listener() {
@Override
public void onResponse(String s) {
onMySuccess(s);
}
};
return mListener;
}
public ErrorListener errorListener(){
mErrorListener = new ErrorListener() {
@Override
public void onErrorResponse(VolleyError volleyError) {
onMyError(volleyError);
}
};
return mErrorListener;
}
可以看到,抽象类中定义了两个方法loadingListener()和errorListener(),分别返回监听器Listener和ErrorListener,并在方法中调用抽象方法,将监听器作为参数传入。当重新new StringRequest请求时便要求重写onMySuccess(String result)和onMyError(VolleyError error)方法。
图片获取与图片缓存
图片获取有两个途径,一个通过ImageRequest,另一个通过ImageLoader。
1,new一个ImageRequest对象可以直接从网络上获取图片,构造方法为 new ImageRequest(url, Listener, 0, 0,Bitmap.Config.RGB_565,ErrorListener),这里也可以通过设置第三,四个参数对加载好的图片进行缩放,若均为0则是默认不对加载好的图片进行处理,第五个参数为图片的加载格式。
2,通过ImageLoader也可以对图片进行加载,new ImageLoader(RequestQueue queue, ImageLoader.ImageCache imageCache),可以看出这里需要使用到图片缓存ImageLoader.ImageCache,我们新建一个类实现该缓存接口,并且需要重写void putBitmap(String var1, Bitmap var2)方法,代码如下:
public classBitmapCacheimplementsImageLoader.ImageCache {
publicLruCachecache;
private intmax=10*1024*1024;
publicBitmapCache(){
cache=newLruCache(max){
@Override
protected intsizeOf(String key,Bitmap value) {
returnvalue.getRowBytes()*value.getHeight();
}
};
}
@Override
publicBitmapgetBitmap(String s) {
returncache.get(s);
}
@Override
public voidputBitmap(String s,Bitmap bitmap) {
cache.put(s,bitmap);
}
}
如上所示,我们创建一个缓存对象LruCache,作为底层真正存储图片缓存的工具,其中sizeOf()方法为确定该缓存的最大值。
通过ImageLoader加载图片后即可将相应的缓存放到图片显示控件中。代码如下:
第一段是使用Android原生的ImageView控件显示,第二段是使用volly的netImageView控件显示。
ImageLoader loader =newImageLoader(MyApplication.getHttpQueues(), newBitmapCache());
ImageLoader.ImageListener listener = ImageLoader.getImageListener(iv_img,R.mipmap.ic_launcher,R.mipmap.ic_launcher);
loader.get(url,listener);
//调用volley框架 获取网络请求消息队列,和图片缓存
ImageLoader loader1 =newImageLoader(MyApplication.getHttpQueues(), newBitmapCache());
netImageView.setDefaultImageResId(R.mipmap.ic_launcher);
netImageView.setErrorImageResId(R.mipmap.ic_launcher);
netImageView.setImageUrl(url,loader1);