我们平时开发Android程试中少不了网络请求,而Android本身也提供了HttpURLConnection和HttpClient来进行网络请求通信。可是HttpURLConnection和HttpClient使用起来难免会有些复杂。在2013年Google I/O大会上推出了Volley网络通信框架。Volley的特点是使用简单而且适合数据量不大,通信频繁并发量大的网络请求操作。
Volly的官网地址是:https://developer.android.com/training/volley/index.html,源码于:https://github.com/google/volley中。下载源码后,我们可以将其编译成jar包或aar文件。使用Android Studio打开该项目并在菜单栏中直接点击“Build”-“Make Project”可直接在\ build\outputs\aar\生成aar文件。aar文件里并没有资源,只有一个classes.jar和两个AndroidManifest.xml。所以您可以选择直接从您自己工程项目中导入aar文件或提取jar文件导入来使用。
如果你不想下载源码和编译,可以直接在Gradle中进行依赖就行:
dependencies {
...
compile 'com.android.volley:volley:1.1.1'
}
Volley的使用是非常的简单,实际上就是四个步聚:
1、在AndroidManifest.xml中添加访问网络权限
2、创建请求队列RequestQueue对象
3、创建请求Request对象
4、将Request对象add到RequestQueue对象中
注意:
我们前面介绍Volley时提到,Volley是适合于高并发量的网络请求操作,所以我们不必创建多个RequestQueue对象去请求网络操作,因为这样是非常浪费资源的。一般地我们使用单例在整个项目中使用一个RequestQueue即可。
StringRequest继承于Request,刚刚我们提到的四个步聚中的第3步创建Request对象,现在就使用StringRequest来实现一个网址的请求,然后返回访问结果:
RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
StringRequest stringRequest = new StringRequest(Request.Method.GET, "http://www.xxx.com",
new Response.Listener() {
@Override
public void onResponse(String s) {
// 请求成功
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError volleyError) {
// 请求失败
}
});
requestQueue.add(stringRequest);
示例中首先通过Volley.newRequestQueue方法创建了一个RequestQueue对象;接着要创建一个请求对象StringRequest的对象,StringRequest类构造函数接收四个参数,分别是请求类型(GET或POST)、请求URL、请求成功回调和请求失败回调;最后,将这个StringRequest对象添加到RequestQueue队列就可以大功告成了。
不知读者们有没有发现,StringRequest类有个很大的缺陷,就是不支持传入参数,但我们知道StringRequest是继承于Request,而从源码中可以看到Request类中有一个方法getParams,此方法返回值便是最终请求所求的参数。所以我们将上面的代码稍微修改一下:
RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
StringRequest stringRequest = new StringRequest(Request.Method.GET, "http://www.xxx.com",
new Response.Listener() {
@Override
public void onResponse(String s) {
// 请求成功
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError volleyError) {
// 请求失败
}
}) {
@Override
protected Map getParams() throws AuthFailureError {
Map map = new HashMap();
map.put("params1", "value1");
map.put("params2", "value2");
// ...
return map;
}
};
requestQueue.add(stringRequest);
就这样就可以完美经支持带参数的网络请求,因为我们一般在POST请求中都会带上参数,若不支持的话,那就真得是很废物了。
JsonRequest也是继承于Request,JsonRequest的使用跟StringRequest的使用大同小异,只是在回调的类型中是一个Json对象,而不是String字符串。JsonRequest本身是一个抽象类,它的实现由JsonObjectRequest和JsonArrayRequest来完成,从名字上应该可以猜到,它们的请求,一个是返回接收Json数据,而一个是返回接收Json数组罢了。我们来看看它们的实现:
RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
// 带参数的JsonObjectRequest请求
Map params = new HashMap();
params.put("params1", "value1");
params.put("params2", "value2");
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, "http://www.xxx.com", new JSONObject(params),
new Response.Listener() {
@Override
public void onResponse(JSONObject response) {
// 请求成功
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
// 请求失败
}
});
requestQueue.add(jsonObjectRequest);
// 不带参数的JsonArrayRequest请求
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Request.Method.POST, "http://www.xxx.com", null,
new Response.Listener() {
@Override
public void onResponse(JSONArray jsonArray) {
// 请求成功
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError volleyError) {
// 请求失败
}
});
requestQueue.add(jsonArrayRequest);
相同的道理,ImageRequest同样也继承于Request,我们直接来看看它的使用示例:
RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
ImageRequest imageRequest = new ImageRequest(
"http://xxx.png", // 请求图片地址
new Response.Listener() { // 请求成功回调
@Override
public void onResponse(Bitmap bitmap) {
//imageView.setImageBitmap(bitmap);
}
},
0, // 图片最大宽度,如果比原图小,则会进行压缩处理,0表示获取原图大小不会进行压缩
0, // 图片最大高度,如果比原图小,则会进行压缩处理,0表示获取原图大小不会进行压缩
ImageView.ScaleType.CENTER_INSIDE, // 指定图片进行压缩的缩放类型,默认CENTER_INSIDE,表示保持宽高比例缩小图片
Bitmap.Config.ARGB_8888, // 指定图片的颜色属性,ARGB_8888可以展示最好的颜色属性,每个图片像素占据4个字节的大小,而RGB_565则表示每个图片像素占据2个字节大小
new Response.ErrorListener() { // 请求失败回调
@Override
public void onErrorResponse(VolleyError error) {
//imageView.setImageResource(R.drawable.default_image);
}
});
requestQueue.add(imageRequest);
可以看到ImageRequest的参数跟之前StringRequest和JsonRequest有些不一样。参数说明请看上面代码中的注释。
ImageLoader并非像前面几个XXXRequest一样继承Request类,它的内部使用了ImageRequest来实现,可以说是在ImageRequest基础上的一个升级,它可以对网络请求的图片进行缓存从而可以避免了一些重复的网络请求,所以它的效率比ImageRequest更加高。下面我们来看看示例:
RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
ImageLoader.ImageListener listener = ImageLoader.getImageListener(imageView, R.drawable.default_image, R.drawable.failed_image);
ImageLoader imageLoader = new ImageLoader(requestQueue, new ImageLoader.ImageCache() {
@Override
public void putBitmap(String url, Bitmap bitmap) {
// TODO 在这里要将bitmap添加入缓存
}
@Override
public Bitmap getBitmap(String url) {
// TODO 在这里要做返回缓存中的图片
return null;
}
});
imageLoader.get("http://xxx.png", listener, 100, 100);
说明:
1、第一步,还是定义一个RequestQueue对象;
2、创建一个ImageListener对象,创建方法接收三个参数,第一个参数指定用于显示图片的ImageView控件,第二个参数指定加载图片的过程中显示的图片,第三个参数指定加载图片失败的情况下显示的图片;
3、创建ImageLoader对象,它的构造函数接收两个参数,第一个参数是RequestQueue对象对象,而第二个参数是一个ImageCache类对象,ImageCache类下要实现两个方法,它们是putBitmap和getBitmap。我们前面所说的缓存便是在这里来实现,putBitmap方法中要将请求接收到的bitmap对象添加到缓存中支,而getBitmap方法则通过请求的url来获取在putBitmap方法中添加入缓存的图片。缓存的实现,可以利用LruCache,LruCache是一个泛型类,它是Android3.1让提供的一个缓存类,它内部采用一个LinkedHashMap以强引用的方式存储外界的缓存对象,其提供了get和put方法来完成缓存的获取和添加操作。如果要做到磁盘缓存,还可以使用DiskLruCache,它不属于AndroidSDK一部分,使用DiskLruCache要提前动手下载好,这里就不详情介绍缓存的使用,因为我们今天重点是讲volley的使用。
4、最后,调用ImageLoader的get()方法来加载图片。get方法最后两个参数是设定图片的最大长和宽,默认0表示不压缩,按原图大小。