Android-Universal-ImageLoader源代码分析2
[TOC]
包结构与架构
包的结构与说明
universalimageloader|
|-cache
|-disc
|-memory
|-core
|-assist
|-decode
|-display
|-download
|-imageaware
|-listener
|-process
|-utils
整体设计架构与说明
结构图表示
各模块的说明
整个库一级划分为cache
, core
, util
三个大模块.
core
: 核心模块分为decode(解码)
,display(展示)
,download(下载)
,imageAware(显示图片的包装)
,process(处理图片)
五个重要的模块.此外,尤其要注意ImageLoaderEngine
,ImageDecorder
,BitmapDisplayer
,BitmapProcessor
,ImageDownloader
,ImageAware
这几个重要的类.cache
: 缓存模块分为disc
缓存和memory
缓存两个模块utils
:工具类模块, 如缓存工具类|Log|图像处理等.
加载图片流程
用一张图简单的标识图片加载流程
加载流程图
详细执行流程
加载的时序图
loadImage
本质也是调用displayImage
因此直接看displayImage
的执行流程即可.
ImageLoader.getInstance().displayImage(uri, imageview, options, listener);
有缓存的时候, 先去检查缓存.参考流程图
DisplayTask 的详细执行流程图
参考
LoadAndDisplayimageTask
中的run
方法
//TODO UML
缓存算法详解
包结构
缓存算法从缓存位置上划分为两种, memory
和disc
.
|-cache
|-disc
|-impl(具体实现)
|-naming(文件命名工具)
|-DiskCache:interface(对外接口)
|-memory
|-impl(具体实现)
|-BaseMemoryCache
|-LimitedMemoryCache
|-MemoryCache:interface(对外接口)
UML
内存缓存
磁盘缓存
解码器与下载器
//BaseImageDownloader
//根据URI的类型, 获取不同的InputStream
@Override
public InputStream getStream(String imageUri, Object extra) throws IOException {
switch (Scheme.ofUri(imageUri)) {
case HTTP:
case HTTPS:
return getStreamFromNetwork(imageUri, extra);
case FILE:
return getStreamFromFile(imageUri, extra);
case CONTENT:
return getStreamFromContent(imageUri, extra);
case ASSETS:
return getStreamFromAssets(imageUri, extra);
case DRAWABLE:
return getStreamFromDrawable(imageUri, extra);
case UNKNOWN:
default:
return getStreamFromOtherSource(imageUri, extra);
}
}
//BaseImageDecoders
//将inputStream解码为Bitmap类型
@Override
public Bitmap decode(ImageDecodingInfo decodingInfo) throws IOException {
Bitmap decodedBitmap;
ImageFileInfo imageInfo;
InputStream imageStream = getImageStream(decodingInfo);
if (imageStream == null) {
L.e(ERROR_NO_IMAGE_STREAM, decodingInfo.getImageKey());
return null;
}
try {
imageInfo = defineImageSizeAndRotation(imageStream, decodingInfo);
imageStream = resetStream(imageStream, decodingInfo);
Options decodingOptions = prepareDecodingOptions(imageInfo.imageSize, decodingInfo);
decodedBitmap = BitmapFactory.decodeStream(imageStream, null, decodingOptions);
} finally {
IoUtils.closeSilently(imageStream);
}
if (decodedBitmap == null) {
L.e(ERROR_CANT_DECODE_IMAGE, decodingInfo.getImageKey());
} else {
decodedBitmap = considerExactScaleAndOrientatiton(decodedBitmap, decodingInfo, imageInfo.exif.rotation,
imageInfo.exif.flipHorizontal);
}
return decodedBitmap;
}