赞
踩
在上一篇文章之中,我们分析了StringRequest,并详细介绍了Request对象的生命周期及执行流程;这一章,我们将分析Volley框架中剩下的一个工具类——ImageLoader。
显然的,ImageLoader是Volley框架用以处理远程图片请求的一个工具类。此工具类封装了Volley框架对远程图片的请求、缓存等操作。
既然是Volley框架封装好的类,那么ImageLoader所提供的接口(方法)都应在UI线程之中被调用,同时从网络之中所获取的结果也将会在UI线程之中被响应;而且与Volley框架相比,ImageLoader使用了一个更有效率的方法来使得UI线程来执行对请求结果的响应。
至于Rquest对象,Volley框架也封装了一个ImageRequest类专门处理图像类别的网络请求;在ImageLoader类中,对ImageRequest类还进行了进一步的封装,即BatchedImageRequest类,该类主要增加了一个功能,就是管理所有对此次网络请求敢兴趣的兴趣点。
要学习一个陌生的类,首先是看它所定义的属性,属性表如下:
属性名 | 类型 | 描述 |
mRequestQueue | RequestQueue | RequestQueue对象的引用,用以添加请求到工作队列之中; |
mBatchResponseDelayMs | int | 第一个响应到达之后,到此批响应全部到达之前,等待的毫秒数,默认为100; 即在此毫秒数之中,到达的响应都视为同一批响应。 |
mCache | ImageCache | 图片的一级缓存;ImageCahe为一个接口; |
mInFlightRequests | HashMap | 缓存处于飞行状态之中的请求;避免重复请求; |
mBatchedResponses | HashMap | 同一批次的请求; |
mHandler | Handler | 用于处理批量请求的响应; |
mRunnalbe | Runnable | 用于处理批量请求时回调的方法; |
mInFlightRequests是一个HashMap,主要记录处于飞行状态的Request对象,防止同一url请求重复;关于飞行状态请查看【进阶android】Volley源码分析——Volley的工具【StringRequest】一文。
除了ImageCache接口和BatchedImageRequest类之外,ImageLoader还封装了两个接口:ImageListener和ImageContainer。
ImageListener继承Response.ErrorListener接口;在此基础上它自己又定义了一个onResponse抽象方法;ImageListener接口只服务于ImageLoader类;而Response类中的两个接口却是和Request对象打交道。
ImageContainer类封装所有与图片请求响应相关的数据,主要有四种:成功加载的图片,加载成功(失败)的监听器ImageListener接口,图片请求的缓存key,图片请求的URL;上文提到BatchedImageRequest类的主要功能是管理所有对此次网络请求(Request对象)敢兴趣的兴趣点。而这里的兴趣点这个概念,就是通过ImageContainer类实现。
介绍完主要的属性和响应的内部类、内部接口时,我们便开始分析ImageLoader的工作流程。
public ImageContainer get(String requestUrl, ImageListener imageListener,int maxWidth, int maxHeight)
requestUrl:图片的URL;
- protected void deliverResponse(Bitmap response) {
- mListener.onResponse(response);
- }
该方法调用了监听器mListener的方法;在ImageRequest类中mListener的类型为Response.Listener,并且mListener的值是通过ImageRequest的构造函数传递过来的。如此我们便可以根据上文网络请求流程的分析,知道ImageRequest对象是在ImageLoader类中的get方法进行实例的,具体代码如下:
- public ImageContainer get(String requestUrl, ImageListener imageListener,
- int maxWidth, int maxHeight) {
- ......
-
- // The request is not already in flight. Send the new request to the network and
- // track it.
- Request<?> newRequest =
- new ImageRequest(requestUrl, new Listener<Bitmap>() {
- @Override
- public void onResponse(Bitmap response) {
- onGetImageSuccess(cacheKey, response);//成功获取图片之后,回调的方法
- }
- }, maxWidth, maxHeight,
- Config.RGB_565, new ErrorListener() {
- @Override
- public void onErrorResponse(VolleyError error) {
- onGetImageError(cacheKey, error);//获取图片失败后,回调的方法
- }
- });
-
- ......
- }
通过代码可以看出,ImageRequest通过一个匿名类执行了Response.Listener接口;这个匿名类中的onResponse方法直接调用了ImageLoader的onGetImageSuccess方法。
- private void batchResponse(String cacheKey, BatchedImageRequest request) {
- mBatchedResponses.put(cacheKey, request);//将本次Request请求添加到批量请求集合之中
- // If we don't already have a batch delivery runnable in flight, make a new one.
- // Note that this will be used to deliver responses to all callers in mBatchedResponses.
- //如果我们还没有一个用来处理批量请求的回调方法,创建一个。
- //注意此回调方法将用来处理响应请求中每一个请求。
- if (mRunnable == null) {
- mRunnable = new Runnable() {
- @Override
- public void run() {
- for (BatchedImageRequest bir : mBatchedResponses.values()) {
- for (ImageContainer container : bir.mContainers) {//处理一个请求所有的兴趣点
- // If one of the callers in the batched request canceled the request
- // after the response was received but before it was delivered,
- // skip them.
- if (container.mListener == null) {
- continue;
- }
- if (bir.getError() == null) {
- container.mBitmap = bir.mResponseBitmap;
- container.mListener.onResponse(container, false);//回调兴趣点的方法!
- }......
- }
- }
- mBatchedResponses.clear();//同批次的请求皆被处理,清空
- mRunnable = null;//开始一场新的批量处理任务
- }
-
- };
- // Post the runnable.
- //创建消息后mBatchResponseDelayMs毫秒后,再执行消息
- //mBatchResponseDelay时间内,添加到mBatchedResponses之中的所有Request对象,视为同批次的请求。
- mHandler.postDelayed(mRunnable, mBatchResponseDelayMs);
- }
- }
batchResponse通过向UI现场发送一个定时消息,来实现批量处理一批请求;这种方式与BufferedInputStream有点类似,将物理源(例如文件)中的内容读入一个缓冲区,当缓冲区满了,或者调用了flush方法,则将缓冲区直接返回给调用者。在batchResponse方法之中,mBatchResponseDelay就类似于一个缓冲区,当时间未到时(BufferedInputStream是空间未满时),将接收到的请求添加到缓冲区,时间一到就一次性处理缓冲区中所有的Request对象。
当然由于本人自身水平所限,文章肯定有一些不对的地方,希望大家指出!
愿大家一起进步,谢谢!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。