Volley是个什么鬼
- Volley,是谷歌官方于2013年发布的用于Android平台的网络通信库,能使网络通信更快,更简单,更健壮。
- Volley的特点有如下:网络通信更快、有着高效率的GET、POST及网络图像的异步处理请求机制、能对多个请求进行排序、能对请求的结果进行缓存、能多级别取消请求。
- 适用场景:它适用于网络通信频繁但是数据量不大的场景;然而对于数据量非常大的情况下,它的性能就会非常差。
- Volley名称的由来: a burst or emission of many things or a large amount at once
Volley有啥本事
- Json,图像等异步下载
- 网络请求的排序(scheduling)
- 网络请求的优先级处理
- 缓存
- 多级别取消请求
- 和 Activity 的生命周期联动(Activity 结束时同时取消所有网络请求)
如何获得Volley
- Volley的源码可以利用git命令直接获取:
git clone https://android.googlesource.com/platform/frameworks/volley
- GitHub下载
https://github.com/mcxiaoke/android-volley
- eclipse导入 jar
http://download.csdn.net/detail/wx_lyb/9657301
- Android Studio中在build.gradle中添加
compile 'com.mcxiaoke.volley:library:1.0.19'
Volley之清蒸:StringRequest
- 创建一个RequestQueue
private RequestQueue mRequestQueue;
mRequestQueue = Volley.newRequestQueue(this);
- 创建一个StringRequest对象
- 第一个参数选择Request.Method.GET即get请求方式
- 第二个参数的url地址根据文档所给
- 第三个参数Response.Listener 请求成功的回调
- 第四个参数Response.ErrorListener 请求失败的回调
StringRequest stringRequest = new StringRequest(Request.Method.GET,"http://www.baidu.com",
new Response.Listener<String>() {
@Override
public void onResponse(String s) {
//s即为服务器返回的数据
textView.setText(s);
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError volleyError) {
Log.e("TAG",volleyError.getMessage(),volleyError);
}
});
- 将StringRequest请求对象添加到RequestQueue队列里面
mRequestQueue.add(stringRequest);
- 最后,别忘了在AndroidManifest.xml里声明网络权限
<uses-permission android:name="android.permission.INTERNET"/>
好了,来尝尝味道如何。
Volley之水煮:JsonRequest
JsonRequest是一个抽象类,无法直接创建它的实例,只能从它的子类(JsonObjectRequest和JsonArrayRequest)入手,顾名思义,JsonObjectRequest用于JSON数据,JsonArrayRequest用于JSON数组的。
- 创建一个RequestQueue
private RequestQueue mRequestQueue;
mRequestQueue = Volley.newRequestQueue(this);
- 创建一个JsonObjectRequest对象
- 第一个参数是一个URl ,
- 第二个参数代表Http请求方式,
- 第三个响应监听。RequestQueue将会执行请求,并响应回调onResponse()方法,所以要在onResponse()方法中实现自己的业务逻辑。
- 第四个响应错误监听
String url = "http://www.tngou.net/tnfs/api/classify";
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(url, null,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject jsonObject) {
//Log.d("TAG", jsonObject.toString());
textView.setText(jsonObject.toString());
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError volleyError) {
Log.e("TAG",volleyError.getMessage(),volleyError);
}
});
- 将JsonObjectRequest对象添加到RequestQueue队列里面
mRequestQueue.add(jsonObjectRequest);
第二道菜完成,来尝一尝味道。
Volley之油闷:ImageRequest
- 创建一个RequestQueue
private RequestQueue mRequestQueue;
mRequestQueue = Volley.newRequestQueue(this);
- 创建一个ImageRequest对象
- 第一个参数是url,图片的地址;
- 第二个参数是Listener是请求响应成功的回调;
- 第三个参数maxWidth是图片的最大宽度;
- 第四个参数maxHeight是图片的最大高度;
- 第五个参数是图片的颜色属性;
- 第六个参数ErrorListener是请求响应失败回调。
注意:如果指定的网络图片的宽度或者高度大于这里的最大值,则会对图片进行压缩;指定成0的话,就表示不管图片多大,都不会进行压缩。
Bitmap.Config中ARGB_8888可以展示最好的颜色属性,每个图片像素占据4个字节的大小,而RGB_565则表示每个图片像素占据2个字节大小。
String imgUrl = "http://images.csdn.net/20161018/banner%20all.png";
ImageRequest imageRequest = new ImageRequest(imgUrl,
new Response.Listener<Bitmap>() {
@Override
public void onResponse(Bitmap bitmap) {
//响应成功,显示下载的图片
image.setImageBitmap(bitmap);
}
}, 0, 0, Bitmap.Config.RGB_565, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError volleyError) {
//响应失败,显示默认的图片
image.setImageResource(R.mipmap.ic_launcher);
}
});
- 将ImageRequest对象添加到RequesQueue队列里面
mRequestQueue.add(imageRequest);
第三道菜出锅,请各位客官品尝。
Volley之爆炒:ImageLoader
如果你觉得上一道菜油闷ImageRequest还不足以满足你的味蕾,那么,下面这道菜保证你胃口大开,爆炒ImageLoader。它的内部也是使用ImageRequest来实现的,不过ImageLoader要比ImageRequest更加高效,它不仅可以对图片进行缓存,还可以过滤掉重复的链接,避免重复发送请求。
注意ImageLoader不是继承自Request,所以这道菜的做法也和前面几道菜做法有所不同。
- 创建一个RequestQueue对象。
private RequestQueue mRequestQueue;
mRequestQueue = Volley.newRequestQueue(this);
- 创建一个ImageLoader对象。
ImageLoader imageLoader = new ImageLoader(mRequestQueue, new ImageLoader.ImageCache() {
@Override
public void putBitmap(String url, Bitmap bitmap) {
}
@Override
public Bitmap getBitmap(String url) {
return null;
}
});
- 获取一个ImageListener对象。
- 第一个参数指定用于显示图片的ImageView控件,
- 第二个参数指定加载图片的过程中显示的图片,
- 第三个参数指定加载图片失败的情况下显示的图片。
ImageLoader.ImageListener listener = ImageLoader.getImageListener(image, R.mipmap.ic_launcher, R.mipmap.ic_launcher);
- 调用ImageLoader的get()方法加载网络上的图片。
imageLoader.get("http://p1.qhimg.com/t0176e92390569422fa.jpg", listener);
当然,如果你想对图片的大小进行限制,也可以使用get()方法的重载,指定图片允许的最大宽度和高度
imageLoader.get("http://p1.qhimg.com/t0176e92390569422fa.jpg", listener, 400, 400);
这里的ImageCache对象是还有做任何处理,获取的图片还不能缓存。所以下面就是给这道菜加点佐料(做缓存处理)。
新建一个BitmapCache并实现ImageCache接口。
public class BitmapCache implements ImageLoader.ImageCache {
private LruCache<String, Bitmap> mCache;
public BitmapCache() {
//分配当前应用所占内存的1/8内存用于LruCache图片缓存
int maxSize = (int) (Runtime.getRuntime().maxMemory() / 8);
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);
}
}
将上面的获取ImageLoader对象步骤改一下。
ImageLoader imageLoader = new ImageLoader(mQueue, new BitmapCache());
好了,爆炒ImageLoader这道菜也可以出锅了。客官,请您慢用!
Volley之油炸:NetworkImageView
除了以上两种方式之外,Volley还提供了第三种方式来加载网络图片,即使用NetworkImageView。不同于以上两种方式,NetworkImageView是一个自定义控制,它是继承自ImageView的,具备ImageView控件的所有功能,并且在原生的基础之上加入了加载网络图片的功能。
最后的给各位食客奉上压轴大菜!
- 创建一个RequestQueue对象。
private RequestQueue mRequestQueue;
mRequestQueue = Volley.newRequestQueue(this);
- 创建一个ImageLoader对象。
和上面的ImageLoader获取对象一样
ImageLoader imageLoader = new ImageLoader(mQueue, new BitmapCache());
- 在布局文件中添加一个NetworkImageView控件。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.app.volleydemo.MainActivity">
<com.android.volley.toolbox.NetworkImageView
android:id="@+id/network_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</RelativeLayout>
- 在代码中获取该控件的实例。
networkImageView = (NetworkImageView) findViewById(R.id.network_image);
- 设置要加载的图片地址。
- setDefaultImageResId()方法设置加载中显示的图片;
- setErrorImageResId()方法加载失败时显示的图片;
- setImageUrl()方法加载目标图片的URL地址。
networkImageView.setDefaultImageResId(R.mipmap.ic_launcher);
networkImageView.setErrorImageResId(R.mipmap.ic_launcher);
networkImageView.setImageUrl("http://p8.qhimg.com/t01a7b515e4ac5f6693.jpg", imageLoader);
终于完成了压轴大菜,油炸NetworkImageView!
这里给大家献上上面所有的Demo代码。点击下载Demo源码