Volley使用
创建请求队列
//此RequestQueue是属于专属的activity的,因此需要一个context
RequestQueue mQueue = Volley.newRequestQueue(getApplicationContext());
创建请求
StringRequest
//为StringRequest的构造器,需要请求方法,URL,请求成功监听器,请求失败监听器
public StringRequest(int method, String url, Listener<String> listener, ErrorListener errorListener) {
super(method, url, errorListener);
this.mListener = listener;
}
//创建StringRequest示例
StringRequest mStringRequest = new StringRequest(Request.Method.GET, "https://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);
}
});
StringRequest
使用方法同上
ImageRequest
//示例代码
ImageRequest imageRequest = new ImageRequest(//已经弃用
"https://www.wanandroid.com/blogimgs/bb4937de-b6f3-4c7e-b7d0-66d02f54abee.jpeg",
new Response.Listener<Bitmap>() {
@Override
public void onResponse(Bitmap response) {
iv_image.setImageBitmap(response);
}
}, 0, 0, Bitmap.Config.RGB_565, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
iv_image.setImageResource(R.drawable.ico_default);
}
});
将请求添加到队列中
mQueue.add(mStringRequest);
mQueue.add(mJsonObjectRequest);
mQueue.add(imageRequest);
使用ImageLoader加载图片
内部依然使用ImageRequest实现,构造方法传入一个ImageCache对象用于缓存图片,同时避免重复连接。
还可以设置默认显示图片以及加载错误图片。
ImageLoader imageLoader = new ImageLoader(mQueue, new BitmapCache());
//Listener参数(ImageView,默认图片,错误图片),也可以设置最大宽度和最大高度
ImageLoader.ImageListener listener = ImageLoader.getImageListener(iv_image, R.drawable.ico_default, R.drawable.ico_default);
imageLoader.get("https://www.wanandroid.com/blogimgs/bb4937de-b6f3-4c7e-b7d0-66d02f54abee.jpeg", listener);
使用NetworkImageView加载图片
与ImageLoader不同的是,本方式是将NetworkImageView当做空间来使用,而ImageLoader是将图片资源加载进入控件中。
ImageLoader imageLoader = new ImageLoader(mQueue, new BitmapCache());
nv_image.setDefaultImageResId(R.drawable.ico_default);
nv_image.setErrorImageResId(R.drawable.ico_default);
nv_image.setImageUrl("https://www.wanandroid.com/blogimgs/bb4937de-b6f3-4c7e-b7d0-66d02f54abee.jpeg", imageLoader);
源码分析
- 创建访问队列
根据Android系统版本来确定用HttpURLCollection还是HttpClient,然后再调用队列的start()方法。 - 创建线程
创建5个线程(1个缓冲调度线程+4个网络调度线程)
public void start() {
stop();
mCacheDispatcher = new CacheDispatcher(mCacheQueue, mNetworkQueue, mCache, mDelivery);
mCacheDispatcher.start();//创建缓冲线程完毕
for (int i = 0; i < mDispatchers.length; i++) {
NetworkDispatcher networkDispatcher = new NetworkDispatcher(mNetworkQueue, mNetwork,
mCache, mDelivery);
mDispatchers[i] = networkDispatcher;
networkDispatcher.start();
}//创建网络调度线程完毕
}
- 添加请求
首先通过执行request.shouldCache()方法判断request是否应该缓存,默认情况下是true,也就是所有的请求默认都要缓存。如果request不需要缓存的话,把请求放进网络请求队列,如果request需要缓存那就放进缓存队列。添加到各自的队列中,然后缓存线程和网络调度线程分别处理两个队列。 - CacheDispatcher工作流程
判断请求是否被取消,如果请求没有被取消则判断是否存在缓存,如果存在并且没有过期,则将响应回调给主线程;如果没有,则将请求添加在网络调度线程中。 - NetworkDispatcher工作流程
网络调度线程也是不断地从队列中取出请求并且判断该请求是否被取消了。如果该请求没有被取消,就去请求网络。请求网络时调用Network的performRequest()方法。
调用成功之后会将响应结果存在缓存中,并且调用this.mDelivery.postResponse(request,volleyError1)回调给主线程。
如果响应成功将会执行Request的deliverResponse方法,并把响应结果传进去,如果响应失败,就执行deliverError方法,并把响应失败的对象传进去。 - 监听器更新
通过之前重写的访问成功和失败的监听器进行主线程的响应更新。
注:
优点:
- 自动的调度网络请求
- 多并发的网络请求
- 可以缓存http请求
- 支持请求的优先级
- 支持取消请求的API,可以取消单个请求,可以设置取消请求的范围域。
- 代码标准化,使开发者更容易专注于我们的业务的逻辑处理
- 更容易给UI填充来自网络请求的数据,通过Handler进行通信
- 缺点:
- 非常不适合大的文件流操作,例如上传和下载。因为Volley会把所有的服务器端返回的数据在解析期间缓存进内存。
- 只支持http请求
- 图片加载性能一般
- 默认开启了5个线程,可以通过使用线程池进行线程管理,不至于资源浪费。