简介
Volley可是说是把AsyncHttpClient和Universal-Image-Loader的优点集于了一身,既可以像AsyncHttpClient一样非常简单地进行HTTP通信,也可以像Universal-Image-Loader一样轻松加载网络上的图片。除了简单易用之外,Volley在性能方面也进行了大幅度的调整,它的设计目标就是非常适合去进行数据量不大,但通信频繁的网络操作,而对于大数据量的网络操作,比如说下载文件等,Volley的表现就会非常糟糕。
目的
- 本文针对Volley的4种Request以及ImageLoader和NetworkImageView的基本用法做简单的讲解
由于Volley是要访问网络的,因此不要忘记在你的AndroidManifest.xml中添加如下权限:
<uses-permission android:name="android.permission.INTERNET" />
StringRequest
- GET
// 一个Activity创建一个RequestQueue实例
RequestQueue mQueue = Volley.newRequestQueue(context);
// 默认请求方式为GET,Listener,ErrorListener是请求结果的监听接口,是在UI线程中运行的
StringRequest stringRequest = new StringRequest("http://www.baidu.com",
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
Log.d("TAG", response);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e("TAG", error.getMessage(), error);
}
});
// 添加到请求队列中等待执行
mQueue.add(stringRequest);
- POST
// 这里添加Method.POST并通过重写Request的getParams()方法添加请求参数
StringRequest stringRequest = new StringRequest(Method.POST, url, listener, errorListener) {
@Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> map = new HashMap<String, String>();
map.put("params1", "value1");
map.put("params2", "value2");
return map;
}
};
mQueue.add(stringRequest);
- 可以看出,对于请求Volley已经相当不错的封装,沿着这个思路,或许我们可以在做个封装,这样就对每次请求都不用写大量重复的代码,如果你有好的封装想法,非常期待你的分享,这里我mark一下
JsonObjectRequest
- JsonObjectRequest的用法与StringRequest用法差不多
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest("http://m.weather.com.cn/data/101010100.html", null,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
Log.d("TAG", response.toString());
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e("TAG", error.getMessage(), error);
}
});
mQueue.add(jsonObjectRequest);
JsonArrayRequest
- JsonArrayRequest的用法与StringRequest用法差不多
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest("http://m.weather.com.cn/data/101010100.html", null,
new Response.Listener<JsonArray>() {
@Override
public void onResponse(JsonArray response) {
Log.d("TAG", response.toString());
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e("TAG", error.getMessage(), error);
}
});
mQueue.add(jsonArrayRequest);
ImageRequest
- ImageRequest构造函数有七个参数,分别是图片的url地址,请求成功监听接口,要将图片压缩后的宽度、高度,图片的缩放方式,图片的配置,请求错误的监听接口。
- 这里当传入图片的宽度、高度为0、0时,不会对图片进行压缩
- 在这个ImageRequest中,有平常开发时一些需要特别注意的知识点,就是关于图片的压缩缓存避免OOM的问题,关于Volley的图片处理我会另外写一篇博文记录下。
ImageRequest imageRequest = new ImageRequest(
"http://developer.android.com/images/home/aw_dac.png",
new Response.Listener<Bitmap>() {
@Override
public void onResponse(Bitmap response) {
imageView.setImageBitmap(response);
}
}, 0, 0, ImageView.ScaleType.CENTER_INSIDE, Bitmap.Config.RGB_565, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
imageView.setImageResource(R.drawable.default_image);
}
});
mQueue.add(imageRequest);
小结一下,上面已经已经列出Volley为我们封装好常用的4种请求,使用过程可总结为: 初始化RequestQueue -> 创建Request -> 添加到RequestQueue
ImageLoader
// 初始化ImageLoader,第一个参数为RequestQueue,第二个参数为图片缓存接口
ImageLoader imageLoader = new ImageLoader(mQueue, new ImageCache() {
@Override
public void putBitmap(String url, Bitmap bitmap) {
}
@Override
public Bitmap getBitmap(String url) {
return null;
}
});
// 根据imageview获取ImageListener,参数分别为ImageView,默认展示的图片,请求失败展示的图片
ImageListener listener = ImageLoader.getImageListener(imageView, R.drawable.default_image, R.drawable.failed_image);
// 通过imageloader加载图片
//imageLoader.get("https://img-my.csdn.net/uploads/201404/13/1397393290_5765.jpeg", listener);
// 通过imageloader加载图片,参数分别为图片url,该图片的监听接口,图片的宽度,高度
imageLoader.get("https://img-my.csdn.net/uploads/201404/13/1397393290_5765.jpeg", listener, 200, 200);
- 上面的ImageCache只是一个接口,要真正实现图片的缓存需要自定义缓存策略存储BItmap对象。下面通过LruCache自定义图片缓存
public class BitmapCache implements ImageCache {
private LruCache<String, Bitmap> mCache;
public BitmapCache() {
// 缓存最大内存为10MB
int maxSize = 10 * 1024 * 1024;
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);
}
}
- 它的内部也是使用ImageRequest来实现的,不过ImageLoader明显要比ImageRequest更加高效,因为它不仅可以帮我们对图片进行缓存,还可以过滤掉重复的链接,避免重复发送请求。
说白了ImageLoader是对ImageRequest的封装,这里总结一下使用过程: 创建RequestQueue -> 创建ImageLoader -> 获取ImageListener -> 通过ImageLoader的get()开始加载图片
NetworkImageView
- NetworkImageView是一个继承自ImageView的自定义控件,下面看看其用法。
<!-- NetworkImageView 控件 -->
<com.android.volley.toolbox.NetworkImageView
android:id="@+id/network_image_view"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_gravity="center_horizontal"
/>
networkImageView = (NetworkImageView) findViewById(R.id.network_image_view);
ImageLoader ImageLoader = ...;
// 设置NetworkImageView 图片资源
networkImageView.setDefaultImageResId(R.drawable.default_image);
networkImageView.setErrorImageResId(R.drawable.failed_image);
networkImageView.setImageUrl("https://img-my.csdn.net/uploads/201404/13/1397393290_5765.jpeg",
imageLoader);
可以看出NetworkImageView其实是对ImageView跟ImageLoader的封装,这样的封装真的需要慢慢体会理解,这里mark一下,哈哈,没事可以看看
这里图片的宽高是根据控件的宽高获取,如果把NetworkImageView的layout_width和layout_height都设置成wrap_content就可以了,这样NetworkImageView就会将该图片的原始大小展示出来,不会进行任何压缩。
光是用法来说,Volley确实是值得学习学习,这里总结一下NetworkImageView的使用过程:创建RequestQueue -> 在布局中定义NetworkImageView并获取控件 -> 创建一个ImageLoader -> 设置NetworkImageView要加载图片的url(还可以设置setErrorImageResId和setDefaultImageResId)
总结
- 最后少不了总结,上面已经讲了Volley的4种Request以及ImageLoader和NetworkImageView的基本用法,问一下自己会用了吗??
现在已经写了关系Volley源码分析的相关文章,有兴趣的博友可以去看看Volley – 源码分析 和Volley – 图片处理方式源码分析
接下来还写了一篇关于Volley的源码分析,分析有Volley请求的流程,缓存的策略,工作线程的执行分配,接口回调的机制,代码的封装等