开源项目分析之UIL(续)
2015-09-09 10:36
459 查看
先直接上流程图
在上一篇我们大概的浏览了一下图片是怎样网络到本地,然后显示出来的。这一讲我们要分析一些细节问题。
图片的处理思路
该开源项目的处理也是符合真实世界的思路的,有几个问题我们需要理清楚
1.我们拥有什么 图片的url和ImageView
2.我们希望怎样处理图片 从网络上解析bitmap,缓存到磁盘,缓存到本地,显示出来
那么,我就分几个模块分析一下
下载图片
我们之前通过分析指导,下载图片是由一个Runnable来完成的,这是一个异步操作。
LoadAndDisplayImageTask displayTask = new LoadAndDisplayImageTask(engine, imageLoadingInfo, defineHandler(options));
我们通过ImageLoaderEngine来执行这个任务,他内部封装了一个Executor,实际是通过开启子线程来执行这个任务。那么最后的执行实体还是在run方法里面。那么既然我已经开启了一个加载任务,其实是因为之前我们在磁盘和内存缓存中并没有找到。那么我加载到后,就要先缓存在磁盘,内存,然后再开启一个显示图片的任务,当然,此时我们已经得到bitmap了。这里的ImageDownLoader是专门用于从网络去下载图片的,但是呢,他并不是将拿到的输入流直接解析为bitmap,而是将流保存在本地,如果用户选择了缓存到磁盘,那么他将该流缓存在磁盘,并对磁盘中的流进行解析,得到bitmap.这边还有一个解析器,是专门将bitmap流解析为bitmap的,如果你选择了缓存到磁盘,那么我们解析磁盘中的流,否则,直接解析uri,即网络流。反正最后我们得到的肯定是一个bitmap。请注意,这上面的一切都是在子线程中做的。仔细看下图,我们可以发现PreProcessor和PostProcess,前者是拿到bitmap后,缓存到内存之前所做的处理,后者是从缓存中拿出后,准备显示到ImageView上时需要做的处理。后面接着就是开启一个显示的任务。
DisplayBitmapTask displayBitmapTask = new DisplayBitmapTask(bmp, imageLoadingInfo, engine, loadedFrom); runTask(displayBitmapTask, syncLoading, handler, engine);
我们知道,显示图片必须在UI线程完成,那么,他是怎么保证的呢?我们可以看到有defineHandler这个方法
private static Handler defineHandler(DisplayImageOptions options) { Handler handler = options.getHandler(); if (options.isSyncLoading()) { handler = null; } else if (handler == null && Looper.myLooper() == Looper.getMainLooper()) { handler = new Handler(); } return handler; }
他必须确保Handler是和主轮询器绑定的,也就是在主线程中。
磁盘缓存
这里面他默认用的是LruDiskCache,那么我们就一起来看一看他是怎么缓存的,又是怎么取出的呢?
这其实是一个自己封装的类,其实质还是用的总所周知的DiskLruCache.毕竟为了实现一些特殊的需求,LruDiskCache需要更多的参数。
LruDiskCache(individualCacheDir,reserveCacheDir,diskCacheFileNameGenerator, diskCacheSize,diskCacheFileCount)
第一个参数 是我们要缓存的目录,第二个是备用的,第三个是名字产生器,就是根据uri来产生一个缓存的文件的名字。
1.怎么保存的呢?
save 好吧,必须要分析一下DiskLruCache的内部类Editor了。它里面有个成员变量written
private Editor(Entry entry) { this.entry = entry; this.written = (entry.readable) ? null : new boolean[valueCount]; }
看看他是怎么初始化的,这个valueCount表示的是你的缓存文件要保存的数量。那么他又是怎么实现
一个key值对应多个缓存文件的呢? 他的文件的命名如下:
public File getDirtyFile(int i) { return new File(directory, key + "." + i + ".tmp"); }
当我们调用save的时候,我们就将输出流和该文件绑定起来了。这里面还有些什么dirtyFile和cleanFile的
处理,就不一一详述了。
本地缓存
LruMemoryCache
显示
BitMapDisplayer 反正最后走到了ViewAware里面,进行了一个判断
if (Looper.myLooper() == Looper.getMainLooper()) {
先说到这吧,最重要的是把我思路,整个流程到底是怎么走的,然后再分析一些细节的处理,如果有特殊需求
可以灵活的更改逻辑。
相关文章推荐
- Ruby微信开发的几个开源项目介绍
- 利用AJAX开源项目 在网页里播放视频实现方法
- 使用PHP把HTML生成PDF文件的几个开源项目介绍
- nice-repo 搜集优秀的开源项目
- 关于开源项目《Scavenger》
- 如何做一个真正牛X 的开源项目
- 我用过的几个开源GIS软件
- 10款GitHub上最火爆的国产开源项目
- 参与到开原项目中去
- 10个关于人工智能和机器学习的有趣开源项目
- Firefly-RK3288系统界面预览
- Android非常有用的开源库介绍整理
- 需求加入开源项目,为社区做贡献
- gnome-logs开发记录1--起源--Gnome开发记录
- gnome-logs开发记录4--noob重构代码就是这个feel
- gnome-logs开发记录3--修复bug726228+杂记
- 成也JAVA 败也JAVA
- 如何做一个牛X的开源项目
- java 技术写架构的几大重点