Volley 除了简单易用之外,在性能方面也进行了大幅度的调整,它的设计目标就是非常适合去进行数据量不大,但通信频繁的网络操作,而不能用于大数据量的网络操作,比如说下载文件等。
导包并在build.gradle中加入这句话:
compile 'eu.the4thfloor.volley:com.android.volley:2015.05.28'
使用:
(一)StringRequest
1,下载String类型数据
(1)首先:需要获取到一个RequestQueue(消息队列)对象
RequestQueue requestQueue;
requestQueue = Volley.newRequestQueue(this);
(2)要发出一条HTTP请求,我们还需要创建一个StringRequest对象:
StringRequest stringRequest = new StringRequest("", new Response.Listener<String>() {
@Override
public void onResponse(String response) {
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
});
构造方法:
第一个参数: 请求地址
第二个参数: 请求成功监听器
第三个参数: 请求失败
StringRequest(String url, Listener<String> listener, ErrorListener errorListener)(GET请求)
第一个参数: 请求方式
第二个参数: 请求地址
第三个参数: 请求成功监听器(数据返回就在这里,不管是正确的还是错误的)
第四个参数: 请求失败(指网络失败,没有返回数据,网络中断等原因造成的请求失败)
StringRequest(int method, String url, Listener<String> listener,ErrorListener errorListener)
(3)将这个StringRequest对象添加到RequestQueue里面
requestQueue.add(stringRequest);
(4)添加访问网络的权限
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
(二)JsonRequest
JsonRequest的用法。类似于StringRequest;
JsonRequest是一个抽象类,因此我们无法直接创建它的实例,那么只能从它的子类入手了;
JsonRequest有两个直接的子类:
JsonObjectRequest:用于请求一段JSON数据
JsonArrayRequest: 用于请求一段JSON数组
使用步骤:
(1)new 一个JsonRequest对象
-
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); } });
-
(2)将这个对象添加到消息队列中
注意点: 服务器返回给我们的数据是JSON格式的
(三)ImageRequest
ImageRequest 与StringRequest和JsonRequest类似,都是继承自Request,用法也类似,三者的使用步骤如下:
1. 创建一个RequestQueue对象。
2. 创建一个Request对象。
3. 将Request对象添加到RequestQueue里面。
不同的只是名称和构造函数不同罢了。
(1)ImageRequest 构建对象:
-
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, Config.RGB_565, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { imageView.setImageResource(R.drawable.default_image); } });
-
构造函数为:
ImageRequest(String url, Response.Listener<Bitmap> listener, int maxWidth, int maxHeight,Config decodeConfig, Response.ErrorListener errorListener)
六个参数:
第一个参数:url 图片的URL地址
第二个参数: 图片请求成功的回调
第三、第四个参数:指定的网络图片的最大宽度和最大高度,如果宽高度与指定不符,则进行压缩,如果都设置为0 ,就是不会压缩
第五个参数:指定图片的颜色属性
第六个参数:图片请求失败的回调
(2) 将此对象添加到消息队列中即可。
(四)ImageLoader
ImageLoader要比ImageRequest更加高效,因为它不仅可以帮我们对图片进行缓存,还可以过滤掉重复的链接,避免重复发送请求;
由于ImageLoader已经不是继承自Request的了,所以其用法也和我们之前学到的内容有所不同,总结起来大致可以分为以下四步:
1. 创建一个RequestQueue对象。
2. 创建一个ImageLoader对象。
3. 获取一个ImageListener对象。
4. 调用ImageLoader的get()方法加载网络上的图片。
如下:
1. 新建图片获取加载工具对象,利用缓存
创建缓存:
long l = Runtime.getRuntime().totalMemory()/8 ;
final LruCache<String, Bitmap> lruCache = new LruCache<String, Bitmap>((int) l) {//此处l是上面获取的程序当前程序的8分之一
@Override
protected int sizeOf(String key, Bitmap value) {//返回每个缓存的大小
return value.getRowBytes() * value.getHeight() / 1024;
}
};// 创建系统自带的缓存,缓存最大值为内存最大值的1/8
2,新建ImageLoader对象
构造函数:
两个参数:
第一个参数就是RequestQueue对象
第二个参数是一个ImageCache对象
ImageLoader imageLoader;
imageLoader = new ImageLoader(requestQueue, new ImageLoader.ImageCache() {
@Override
public Bitmap getBitmap(String url) {//从缓存中获取图片,是在 get 方法执行的时候才来,因为需要 url
LogUitls.e("volley", "获取缓存图片");
Bitmap bitmap = lruCache.get(url);
return bitmap;
}
@Override
public void putBitmap(String url, Bitmap bitmap) {//往缓存中存放图片,这里的URL值是什么?缓存地址还是上面的下载地址?
LogUitls.e("volley", "将图片存放到缓存中");
lruCache.put(url, bitmap);
}
});
(3)get方法
get方法参数:
第一个参数:图片的URL地址
第二个参数:ImageListener对象
ImageListener构造函数参数:
第一个参数:要显示图片的控件
第二个参数:加载图片的过程中显示的图片
第三个参数: 加载图片失败的情况下显示的图片
imageLoader.get("http://www.baidu.com/img/bd_logo1.png",
ImageLoader.getImageListener(imageView, R.mipmap.ic_launcher, R.mipmap.ic_launcher));
ImageLoader.getImageListener的缺点:仅适合没有复用控件的时候使用, listview 中使用会导致错乱,因为没有判断返回的图片
(五)NetworkImageView
NetworkImageView是一个自定义控制,它是继承自ImageView的,具备ImageView控件的所有功能,并且在原生的基础之上加入了加载网络图片的功能。
NetworkImageView控件的用法要比前两种方式更加简单,大致可以分为以下五步:
1. 创建一个RequestQueue对象。
2. 创建一个ImageLoader对象。
3. 在布局文件中添加一个NetworkImageView控件。4. 在代码中获取该控件的实例。
5. 设置要加载的图片地址。
从第三步起:
先设置控件:
-
<com.android.volley.toolbox.NetworkImageView android:id="@+id/network_image_view" android:layout_width="200dp" android:layout_height="200dp" android:layout_gravity="center_horizontal" />
接着在Activity获取到这个控件的实例。
然后调用此控件的方法给它设置加载中显示的图片和加载失败后显示的图片、图片的URL地址。
-
networkImageView.setDefaultImageResId(R.drawable.default_image); networkImageView.setErrorImageResId(R.drawable.failed_image); networkImageView.setImageUrl("//img-my.csdn.net/uploads/201404/13/1397393290_5765.jpeg", imageLoader);
由此看来,NetworkImageView控件比上述的两种方法更加简便,且NetworkImageView并不需要提供任何设置最大宽高的方法也能够对加载的图片进行压缩。
这是因为NetworkImageView是一个控件,在加载图片的时候它会自动获取自身的宽高,然后对比网络图片的宽度,再决定是否需要对图片进行压缩。
如果你不想对图片进行压缩的话,其实也很简单,只需要在布局文件中把NetworkImageView的layout_width和layout_height都设置成wrap_content就可以了,这样NetworkImageView就会将该图片的原始大小展示出来,不会进行任何压缩。