【进阶android】Volley源码分析——Volley的工具【ImageLoader】
来源:互联网 发布:C语言多个else if用法 编辑:程序博客网 时间:2024/06/05 04:15
在上一篇文章之中,我们分析了StringRequest,并详细介绍了Request对象的生命周期及执行流程;这一章,我们将分析Volley框架中剩下的一个工具类——ImageLoader。
显然的,ImageLoader是Volley框架用以处理远程图片请求的一个工具类。此工具类封装了Volley框架对远程图片的请求、缓存等操作。
既然是Volley框架封装好的类,那么ImageLoader所提供的接口(方法)都应在UI线程之中被调用,同时从网络之中所获取的结果也将会在UI线程之中被响应;而且与Volley框架相比,ImageLoader使用了一个更有效率的方法来使得UI线程来执行对请求结果的响应。
至于Rquest对象,Volley框架也封装了一个ImageRequest类专门处理图像类别的网络请求;在ImageLoader类中,对ImageRequest类还进行了进一步的封装,即BatchedImageRequest类,该类主要增加了一个功能,就是管理所有对此次网络请求敢兴趣的兴趣点。
一、ImageLoader中的相关属性
要学习一个陌生的类,首先是看它所定义的属性,属性表如下:
属性名类型描述
mRequestQueue
RequestQueueRequestQueue对象的引用,用以添加请求到工作队列之中;mBatchResponseDelayMs
int第一个响应到达之后,到此批响应全部到达之前,等待的毫秒数,默认为100;即在此毫秒数之中,到达的响应都视为同一批响应。
mCache
ImageCache
图片的一级缓存;ImageCahe为一个接口;mInFlightRequests
HashMap缓存处于飞行状态之中的请求;避免重复请求;mBatchedResponses
HashMap同一批次的请求; mHandler
Handler用于处理批量请求的响应;mRunnalbeRunnable用于处理批量请求时回调的方法; ImageLoader采用两个级别来缓存请求;一级缓存是一个ImageCache接口的实现类;二级缓存就是我们之前分析过的Volley框架之中的Cache接口。ImageCache缓存具体的图片对象,而Cache缓存则主要原始的响应内容。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的工作流程。
二、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方法。
由图可以看出,网络响应处理的总体流程并不复杂;其需要注意的是第三步:批量处理请求的响应,具体执行这一步的是ImageLoader的batchResponse方法。
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对象。
三 总结
至此,关于Volley框架的五篇分析文章就至此结束。当然由于本人自身水平所限,文章肯定有一些不对的地方,希望大家指出!
愿大家一起进步,谢谢!
- 【进阶android】Volley源码分析——Volley的工具【ImageLoader】
- 【进阶android】Volley源码分析——Volley的流程
- 【进阶android】Volley源码分析——Volley的线程
- 【进阶android】Volley源码分析——Volley的缓存
- 【进阶android】Volley源码分析——Volley的工具【StringRequest】
- 【进阶android】Volley源码分析——总述
- Volley源码分析(四)——ImageLoader
- android Volley的源码分析
- android-----Volley框架使用ImageLoader加载图片源码分析
- Android——volley源码分析
- Volley框架中ImageLoader源码分析
- Android-Volley源码分析
- [Android]volley源码分析
- Android-Volley源码分析
- android Volley 源码分析
- Volley的源码分析
- Volley的ImageLoader用法
- Android - Volley的ImageLoader下载图片
- 算法分析-查找单链表中的倒数第k个元素和中间元素
- Unity3D 图片空间和内存占用分析
- hook+线段树(二)小结区间操作
- storm原理介绍
- 理解Nodejs的Event Loop
- 【进阶android】Volley源码分析——Volley的工具【ImageLoader】
- trident原理及编程指南
- iOS -UI-06 UIImageView 动画
- oc第一节作业
- 杭电 2120 Ice_cream's world I
- arm 中断配置以及处理的源码分析
- Java日志框架——JCL
- 格式化说明符以及修饰符(整理)
- log4j配置多个日志输出文件