Android-Universal-Image-Loader主要功能和图片加载过程
2015-02-25 10:50
399 查看
主要功能
1. 多线程图片加载,无论是同步还是异步加载2. 对图片加载的可以进行多种配置
3. 对每一个图片展示定制多种选项
4. 图片缓存在内存和磁盘中
5. 监听图片加载的过程
可以使用的uri例子
"http://site.com/image.png"// from Web"file:///mnt/sdcard/image.png"// from SD card
"file:///mnt/sdcard/video.mp4"// from SD card (video thumbnail)
"content://media/external/images/media/13"// from content provider
"content://media/external/video/media/13"// from content provider (video thumbnail)
"assets://image.png"// from assets
"drawable://"+ R.drawable.img//
from drawables (non-9patch images)
图片加载过程
这张图描述了加载过程:
1.展示图片ImageLoader.class
<pre name="code" class="java">/** * Adds display image task to execution pool. Image will be set to ImageAware when it's turn.<br /> * <b>NOTE:</b> {@link #init(ImageLoaderConfiguration)} method must be called before this method call * * @param uri Image URI (i.e. "http://site.com/image.png", "file:///mnt/sdcard/image.png") * @param imageAware {@linkplain com.nostra13.universalimageloader.core.imageaware.ImageAware Image aware view} * which should display image * @param options {@linkplain com.nostra13.universalimageloader.core.DisplayImageOptions Options} for image * decoding and displaying. If <b>null</b> - default display image options * {@linkplain ImageLoaderConfiguration.Builder#defaultDisplayImageOptions(DisplayImageOptions) * from configuration} will be used. * @param listener {@linkplain ImageLoadingListener Listener} for image loading process. Listener fires * events on UI thread if this method is called on UI thread. * @param progressListener {@linkplain com.nostra13.universalimageloader.core.listener.ImageLoadingProgressListener * Listener} for image loading progress. Listener fires events on UI thread if this method * is called on UI thread. Caching on disk should be enabled in * {@linkplain com.nostra13.universalimageloader.core.DisplayImageOptions options} to make * this listener work. * @throws IllegalStateException if {@link #init(ImageLoaderConfiguration)} method wasn't called before * @throws IllegalArgumentException if passed <b>imageAware</b> is null */ public void displayImage(String uri, ImageAware imageAware, DisplayImageOptions options, ImageLoadingListener listener, ImageLoadingProgressListener progressListener) { checkConfiguration(); if (imageAware == null) { throw new IllegalArgumentException(ERROR_WRONG_ARGUMENTS); } if (listener == null) { listener = emptyListener; } if (options == null) { options = configuration.defaultDisplayImageOptions; } /** * 判断uri是否为空 */ 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; } //获取图片的大小 ImageSize targetSize = ImageSizeUtils.defineTargetSizeForView(imageAware, configuration.getMaxImageSize()); //生成存储的一个key 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); } } }
如果在图片在内存中就使用ProcessAndDisplayImageTask
如果在图片不在内存中就使用LoadAndDisplayImageTask
ProcessAndDisplayImageTask.class
@Override public void run() { L.d(LOG_POSTPROCESS_IMAGE, imageLoadingInfo.memoryCacheKey); BitmapProcessor processor = imageLoadingInfo.options.getPostProcessor(); //处理图像 Bitmap processedBitmap = processor.process(bitmap); //创建显示图片的任务 DisplayBitmapTask displayBitmapTask = new DisplayBitmapTask(processedBitmap, imageLoadingInfo, engine, LoadedFrom.MEMORY_CACHE); LoadAndDisplayImageTask.runTask(displayBitmapTask, imageLoadingInfo.options.isSyncLoading(), handler, engine); }
LoadAndDisplayImageTask.class
@Override public void run() { if (waitIfPaused()) return; if (delayIfNeed()) return; ReentrantLock loadFromUriLock = imageLoadingInfo.loadFromUriLock; L.d(LOG_START_DISPLAY_IMAGE_TASK, memoryCacheKey); if (loadFromUriLock.isLocked()) { L.d(LOG_WAITING_FOR_IMAGE_LOADED, memoryCacheKey); } loadFromUriLock.lock(); Bitmap bmp; try { //检查任务是否存在 checkTaskNotActual(); //获取内存中的图片是否存在 bmp = configuration.memoryCache.get(memoryCacheKey); if (bmp == null || bmp.isRecycled()) { //如果不存在或者被回收了就是尝试去加载图片 bmp = tryLoadBitmap(); if (bmp == null) return; // listener callback already was fired checkTaskNotActual(); checkTaskInterrupted(); //是否在载入内存中进行处理 if (options.shouldPreProcess()) { L.d(LOG_PREPROCESS_IMAGE, memoryCacheKey); bmp = options.getPreProcessor().process(bmp); if (bmp == null) { L.e(ERROR_PRE_PROCESSOR_NULL, memoryCacheKey); } } //在图片不为空并且需要被放入内存中 if (bmp != null && options.isCacheInMemory()) { L.d(LOG_CACHE_IMAGE_IN_MEMORY, memoryCacheKey); configuration.memoryCache.put(memoryCacheKey, bmp); } } else { loadedFrom = LoadedFrom.MEMORY_CACHE; L.d(LOG_GET_IMAGE_FROM_MEMORY_CACHE_AFTER_WAITING, memoryCacheKey); } //在显示钱是否进程处理 if (bmp != null && options.shouldPostProcess()) { L.d(LOG_POSTPROCESS_IMAGE, memoryCacheKey); bmp = options.getPostProcessor().process(bmp); if (bmp == null) { L.e(ERROR_POST_PROCESSOR_NULL, memoryCacheKey); } } checkTaskNotActual(); checkTaskInterrupted(); } catch (TaskCancelledException e) { fireCancelEvent(); return; } finally { loadFromUriLock.unlock(); } DisplayBitmapTask displayBitmapTask = new DisplayBitmapTask(bmp, imageLoadingInfo, engine, loadedFrom); runTask(displayBitmapTask, syncLoading, handler, engine); }
private Bitmap tryLoadBitmap() throws TaskCancelledException { Bitmap bitmap = null; try { //是否在磁盘中存在 File imageFile = configuration.diskCache.get(uri); if (imageFile != null && imageFile.exists()) { //如果存在就载入图片 L.d(LOG_LOAD_IMAGE_FROM_DISK_CACHE, memoryCacheKey); loadedFrom = LoadedFrom.DISC_CACHE; checkTaskNotActual(); bitmap = decodeImage(Scheme.FILE.wrap(imageFile.getAbsolutePath())); } if (bitmap == null || bitmap.getWidth() <= 0 || bitmap.getHeight() <= 0) { //如果没有就重远程加载图片 L.d(LOG_LOAD_IMAGE_FROM_NETWORK, memoryCacheKey); loadedFrom = LoadedFrom.NETWORK; String imageUriForDecoding = uri; if (options.isCacheOnDisk() && tryCacheImageOnDisk()) { imageFile = configuration.diskCache.get(uri); if (imageFile != null) { imageUriForDecoding = Scheme.FILE.wrap(imageFile.getAbsolutePath()); } } checkTaskNotActual(); bitmap = decodeImage(imageUriForDecoding); if (bitmap == null || bitmap.getWidth() <= 0 || bitmap.getHeight() <= 0) { fireFailEvent(FailType.DECODING_ERROR, null); } } } catch (IllegalStateException e) { fireFailEvent(FailType.NETWORK_DENIED, null); } catch (TaskCancelledException e) { throw e; } catch (IOException e) { L.e(e); fireFailEvent(FailType.IO_ERROR, e); } catch (OutOfMemoryError e) { L.e(e); fireFailEvent(FailType.OUT_OF_MEMORY, e); } catch (Throwable e) { L.e(e); fireFailEvent(FailType.UNKNOWN, e); } return bitmap; }
相关文章推荐
- Android Universal Image Loader加载 ListView 滑动过程中图片显示重复错位闪烁问题
- 图片异步加载框架 Android-Universal-Image-Loader
- Android图片异步加载之Android-Universal-Image-Loader
- Android-Universal-Image-Loader图片异步加载并缓存
- Android-Universal-Image-Loader 图片异步加载类库的使用(超详细配置)
- 【移动开发】Android图片异步加载之Android-Universal-Image-Loader使用
- 图片异步加载框架 Android-Universal-Image-Loader
- Android图片异步加载之Android-Universal-Image-Loader使用
- Android-Universal-Image-Loader 图片异步加载类库的使用(超详细配置)
- 图片异步加载框架 Android-Universal-Image-Loader
- Android-Universal-Image-Loader 图片异步加载类库的使用(超详细配置)
- Android图片异步加载之Android-Universal-Image-Loader
- [置顶] Android图片异步加载之Android-Universal-Image-Loader
- Android-Universal-Image-Loader 图片异步加载框架
- Android-Universal-Image-Loader异步加载图片框架学习研究
- Android利用universal-image-loader异步加载大量图片完整示例
- 【移动开发】Android图片异步加载之Android-Universal-Image-Loader使用 推荐
- Android-Universal-Image-Loader 异步加载图片
- [学习总结]9、Android-Universal-Image-Loader 图片异步加载类库的使用(超详细配置)
- 图片异步加载框架 Android-Universal-Image-Loader