【Android框架】Android-universal-image-loader源码阅读(一)
来源:互联网 发布:r软件 编辑:程序博客网 时间:2024/05/01 11:48
图片加载是个非常常见的APP功能,而如今框架横行,在图片加载方面出现了很多图片加载框架:Android-universal-image-loader,pacasso,Fresco,Glide等等图片加载框架。今天我们单独研究下Android-univeral-image-loader图片加载框架。Android-universal-image-loader在很多APP中有使用,今天开始解读下源码,分析它的原理,讲讲自己的浅见。
先来看看Android-universal-image-loader图片加载框架的组成结构:
主要有三部分组成,cache缓存,core核心加载部分,utils工具类部分。
下面来一步步抽丝剥茧。
简单的讲就是 ImageLoader 收到加载及显示图片的任务,并将它交给 ImageLoaderEngine , ImageLoaderEngine 分发任务到具体线程池去执行,任务通过 Cache 及 ImageDownloader 获取图片,中间可能经过 BitmapProcessor 和 ImageDecoder 处理,最终转换为 Bitmap 交给 BitmapDisplayer 在 ImageAware 中显示。
先看简单的imageView加载指定url路径下的网络图片:
ImageLoader imageLoader = ImageLoader.getInstance(); //获得单例//加载到imageView中展示imageLoader.displayImage(imageUri, imageView);
调用displayImage(imageUri,imageView);
然后是displayImage(uri, imageAware, options, null, listener,progressListener);
最终调用:
public void displayImage(String uri, ImageAware imageAware, DisplayImageOptions options, ImageSize targetSize, ImageLoadingListener listener, ImageLoadingProgressListener progressListener) { checkConfiguration(); if (imageAware == null) { throw new IllegalArgumentException(ERROR_WRONG_ARGUMENTS); } if (listener == null) { listener = defaultListener; } if (options == null) { options = configuration.defaultDisplayImageOptions; } if (TextUtils.isEmpty(uri)) { engine.cancelDisplayTaskFor(imageAware); listener.onLoadingStarted(uri, imageAware.getWrappedView()); if (options.shouldShowImageForEmptyUri()) { imageAware.setImageDrawable(options.getImageForEmptyUri(configuration.resources)); } else { imageAware.setImageDrawable(null); } listener.onLoadingComplete(uri, imageAware.getWrappedView(), null); return; } if (targetSize == null) { targetSize = ImageSizeUtils.defineTargetSizeForView(imageAware, configuration.getMaxImageSize()); } String memoryCacheKey = MemoryCacheUtils.generateKey(uri, targetSize); engine.prepareDisplayTaskFor(imageAware, memoryCacheKey); listener.onLoadingStarted(uri, imageAware.getWrappedView()); Bitmap bmp = configuration.memoryCache.get(memoryCacheKey); if (bmp != null && !bmp.isRecycled()) { L.d(LOG_LOAD_IMAGE_FROM_MEMORY_CACHE, memoryCacheKey); if (options.shouldPostProcess()) { ImageLoadingInfo imageLoadingInfo = new ImageLoadingInfo(uri, imageAware, targetSize, memoryCacheKey, options, listener, progressListener, engine.getLockForUri(uri)); ProcessAndDisplayImageTask displayTask = new ProcessAndDisplayImageTask(engine, bmp, imageLoadingInfo, defineHandler(options)); if (options.isSyncLoading()) { displayTask.run(); } else { engine.submit(displayTask); } } else { options.getDisplayer().display(bmp, imageAware, LoadedFrom.MEMORY_CACHE); listener.onLoadingComplete(uri, imageAware.getWrappedView(), bmp); } } else { if (options.shouldShowImageOnLoading()) { imageAware.setImageDrawable(options.getImageOnLoading(configuration.resources)); } else if (options.isResetViewBeforeLoading()) { imageAware.setImageDrawable(null); } ImageLoadingInfo imageLoadingInfo = new ImageLoadingInfo(uri, imageAware, targetSize, memoryCacheKey, options, listener, progressListener, engine.getLockForUri(uri)); LoadAndDisplayImageTask displayTask = new LoadAndDisplayImageTask(engine, imageLoadingInfo, defineHandler(options)); if (options.isSyncLoading()) { displayTask.run(); } else { engine.submit(displayTask); } } }
以上代码有几个值得注意的地方:`
String memoryCacheKey = MemoryCacheUtils.generateKey(uri, targetSize);`//这里是对uri及图片大小生成一个key,在之前的DiskLruCache博客中有提及到
bmp.isRecycled()在很多对象释放的时候需要注意,bmp对象若不释放,最终会造成内存泄漏的结果。
Bitmap bmp = configuration.memoryCache.get(memoryCacheKey);。。。。 !bmp.isRecycled()
需要了解的是ImageLoaderEngine对象
ImageLoaderEngine engine;。。。//ImageView的Id对应图片的Keyengine.prepareDisplayTaskFor(imageAware, memoryCacheKey);
//从内存中获取图片展示options.getDisplayer().display(bmp, imageAware, LoadedFrom.MEMORY_CACHE); listener.onLoadingComplete(uri, imageAware.getWrappedView(), bmp);
下面看看loadImage(String uri, ImageSize targetImageSize, DisplayImageOptions options,ImageLoadingListener listener, ImageLoadingProgressListener progressListener)
//检测Configuration是否为空checkConfiguration(); if (targetImageSize == null) { targetImageSize = configuration.getMaxImageSize(); } if (options == null) { options = configuration.defaultDisplayImageOptions; } //封装imageView呈现所需 url路径,size图片大小,呈现方式 NonViewAware imageAware = new NonViewAware(uri, targetImageSize, ViewScaleType.CROP);//CROP是图片的呈现方式 displayImage(uri, imageAware, options, listener, progressListener);//最后展示
- 【Android框架】Android-universal-image-loader源码阅读(一)
- Android Universal Image Loader 源码分析(一)
- Android开源框架Universal-Image-Loader解析(一)
- Android开源框架Universal-Image-Loader源码解析
- Android 图片加载框架Universal-Image-Loader源码解析
- Universal-Image-Loader源码阅读(35)-
- Android-Universal-Image-Loader(UIL)源码解析(一)
- android图片缓存框架Android-Universal-Image-Loader(二)
- Android Universal Image Loader 源码分析
- Android Universal Image Loader 源码分析
- Android Universal Image Loader 源码分析
- Android Universal Image Loader 源码分析
- Android Universal Image Loader 源码分析
- Android Universal Image Loader 源码分析
- Android Universal Image Loader 源码分析
- Android Universal Image Loader 源码分析
- Android Universal Image Loader 源码分析
- Android Universal Image Loader 源码分析
- 十一周阅读程序5-c
- 输出星号图
- 项目1-程序填空
- LaTeX多行注释
- 静态成员应用
- 【Android框架】Android-universal-image-loader源码阅读(一)
- 第14周项目4-数组类模板
- 风格的结束后是的人和事的符合计划日他
- 第十一周项目四立体类族共有的抽象类
- 功能的计划的唐吉可德同一件事如果回家台日
- 创客教育
- 的感觉可输入哈尔和公司的家事如天哈尔
- Merge Two Sorted Lists
- 第八周项目一(2)—深复制构造函数体验