开源Android-Universal-Image-Loader项目的简介

时间:2022-11-25 20:39:31

抽空看了下github的开源项目:Android-Universal-Image-Loader,感觉里边的内容还是比较多,需要总结。


本文的目的:

           1,项目的整体结构

           2,相关处理的分类

           3,算法相关的总结

           4,多线程的总结


一,代码的整体的结构。

   代码结构图

开源Android-Universal-Image-Loader项目的简介


代码的结构很清新,相关的分类很详细,应该会满足大多数人的需求。此处不涉及如何使用此开源项目,之探讨源码。



二,相关处理的分类(不一一列举,参看代码结构图,即是列举)

   1sdcard文件缓存限制分类

   2sdcard文件命名方法分类

   3,内存缓存限制分类

   4BitmapDisplay的方式


三,算法相关总结

1,生成文件名 md5

      1-1用途:

            MD5 Message DigestAlgorithm 5 信息摘要算法


用于确保信息传输完整一致。让大容量信息在用数字签名软件签署私人密钥。前被“压缩”成一种保密的格式(就是把一个任意长度的字节串变换成一定长的十六进制的数字串)。任何人对文件做了任何改动,其MD5值都会发生变化。可称之为“数字指纹”。

      1-2 原理:

MD5512位分组来处理输入的信息,且每一分组又被划分为1632位子分组,经过了一系列的处理后,算法的输出由四个32位分组组成,将这四个32位分组级联后将生成一个128位散列值。

          w:基本的意思应该是数据分组,组合,然后经过一系列复杂的运算。


2,内存缓存方式

2-1FIFOLimitedMemoryCache

对此类的注释如下:

12345678910 /** * Limited {@link Bitmap bitmap} cache. Provides {@link Bitmap bitmaps} storing. Size of all stored bitmaps will not to * exceed size limit. When cache reaches limit size then cache clearing is processed by FIFO principle.<br /> * <br /> * <b>NOTE:</b> This cache uses strong and weak references for stored Bitmaps. Strong references - for limited count of * Bitmaps (depends on cache size), weak references - for all other cached Bitmaps. * * @author Sergey Tarasevich (nostra13[at]gmail[dot]com) * @since 1.0.0 */

         FIFO Priciple First inFirst Out

优点:先进入的先完成并先退出,跟着才执行第二条指令

缺点:只能顺序写入数据,顺序的读出数据。


2-2LRULimitedMemoryCache

对此类的注释如下:

12345678910 /** * Limited {@link Bitmap bitmap} cache. Provides {@link Bitmap bitmaps} storing. Size of all stored bitmaps will not to * exceed size limit. When cache reaches limit size then the least recently used bitmap is deleted from cache.<br /> * <br /> * <b>NOTE:</b> This cache uses strong and weak references for stored Bitmaps. Strong references - for limited count of * Bitmaps (depends on cache size), weak references - for all other cached Bitmaps. * * @author Sergey Tarasevich (nostra13[at]gmail[dot]com) * @since 1.3.0 */

         LRU: least recently used

实质:当内存不够时,将清掉使用时间最老的缓存。


2-3 LruMemoryCache

对此类的注释如下:

12345678910 /** * A cache that holds strong references to a limited number of Bitmaps. Each time a Bitmap is accessed, it is moved to * the head of a queue. When a Bitmap is added to a full cache, the Bitmap at the end of that queue is evicted and may * become eligible for garbage collection.<br /> * <br /> * <b>NOTE:</b> This cache uses only strong references for stored Bitmaps. * * @author Sergey Tarasevich (nostra13[at]gmail[dot]com) * @since 1.8.1 */

实质:当某一个bitmap被访问时,它被移到队首,当内存不够时,从队尾清


2-4UsingFreqLimitedMemoryCache

对此类的注释如下:

1234567891011 /** * Limited {@link Bitmap bitmap} cache. Provides {@link Bitmap bitmaps} storing. Size of all stored bitmaps will not to * exceed size limit. When cache reaches limit size then the bitmap which used the least frequently is deleted from * cache.<br /> * <br /> * <b>NOTE:</b> This cache uses strong and weak references for stored Bitmaps. Strong references - for limited count of * Bitmaps (depends on cache size), weak references - for all other cached Bitmaps. * * @author Sergey Tarasevich (nostra13[at]gmail[dot]com) * @since 1.0.0 */

实质,当内存不够时,将清掉使用频率最低的缓存。


2-5 WeakMemoryCache

弱引用,请参看之前的blog:http://mikewang.blog.51cto.com/3826268/880775


四,多线程:BlockingQueue

参考文章:http://www.cnblogs.com/jackyuj/archive/2010/11/24/1886553.html





1.功能概要

 Android-Universal-Image-Loader是一个开源的UI组件程序,该项目的目的是提供一个可重复使用的仪器为异步图像加载,缓存和显示。

(1).使用多线程加载图片
(2).灵活配置ImageLoader的基本参数,包括线程数、缓存方式、图片显示选项等;
(3).图片异步加载缓存机制,包括内存缓存及SDCard缓存;
(4).采用监听器监听图片加载过程及相应事件的处理;
(5).配置加载的图片显示选项,比如图片的圆角处理及渐变动画。

2.简单实现

ImageLoader采用单例设计模式,ImageLoader imageLoader = ImageLoader.getInstance();得到该对象,每个ImageLoader采用单例设计模式,ImageLoader必须调用init()方法完成初始化。

[java] view plaincopy
  1. //  1.完成ImageLoaderConfiguration的配置  
  2. ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(this)  
  3.     .memoryCacheExtraOptions(480800)          // default = device screen dimensions  
  4.     .discCacheExtraOptions(480800, CompressFormat.JPEG, 75null)  
  5.     .taskExecutor(...)  
  6.     .taskExecutorForCachedImages(...)  
  7.     .threadPoolSize(3)                          // default  
  8.     .threadPriority(Thread.NORM_PRIORITY - 1)   // default  
  9.     .tasksProcessingOrder(QueueProcessingType.FIFO) // default  
  10.     .denyCacheImageMultipleSizesInMemory()  
  11.     .memoryCache(new LruMemoryCache(2 * 1024 * 1024))  
  12.     .memoryCacheSize(2 * 1024 * 1024)  
  13.     .memoryCacheSizePercentage(13)              // default  
  14.     .discCache(new UnlimitedDiscCache(cacheDir))// default  
  15.     .discCacheSize(50 * 1024 * 1024)        // 缓冲大小  
  16.     .discCacheFileCount(100)                // 缓冲文件数目  
  17.     .discCacheFileNameGenerator(new HashCodeFileNameGenerator()) // default  
  18.     .imageDownloader(new BaseImageDownloader(context)) // default  
  19.     .imageDecoder(new BaseImageDecoder()) // default  
  20.     .defaultDisplayImageOptions(DisplayImageOptions.createSimple()) // default  
  21.     .writeDebugLogs()  
  22.     .build();  
  23.   
  24. //  2.单例ImageLoader类的初始化  
  25. ImageLoader imageLoader = ImageLoader.getInstance();  
  26. imageLoader.init(config);  
  27.   
  28. //  3.DisplayImageOptions实例对象的配置  
  29. //      以下的设置再调用displayImage()有效,使用loadImage()无效  
  30. DisplayImageOptions options = new DisplayImageOptions.Builder()  
  31.     .showStubImage(R.drawable.ic_stub)          // image在加载过程中,显示的图片  
  32.     .showImageForEmptyUri(R.drawable.ic_empty)  // empty URI时显示的图片  
  33.     .showImageOnFail(R.drawable.ic_error)       // 不是图片文件 显示图片  
  34.     .resetViewBeforeLoading(false)  // default  
  35.     .delayBeforeLoading(1000)  
  36.     .cacheInMemory(false)           // default 不缓存至内存  
  37.     .cacheOnDisc(false)             // default 不缓存至手机SDCard  
  38.     .preProcessor(...)  
  39.     .postProcessor(...)  
  40.     .extraForDownloader(...)  
  41.     .imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2)// default  
  42.     .bitmapConfig(Bitmap.Config.ARGB_8888)              // default  
  43.     .decodingOptions(...)  
  44.     .displayer(new SimpleBitmapDisplayer()) // default 可以设置动画,比如圆角或者渐变  
  45.     .handler(new Handler())                             // default  
  46.     .build();  
  47.       
  48. //  4图片加载  
  49. //  4.1 调用displayImage  
  50. imageLoader.displayImage(  
  51.     uri,        /* 
  52.                     String imageUri = "http://site.com/image.png";      // from Web 
  53.                     String imageUri = "file:///mnt/sdcard/image.png";   // from SD card 
  54.                     String imageUri = "content://media/external/audio/albumart/13"; // from content provider 
  55.                     String imageUri = "assets://image.png";             // from assets 
  56.                     */  
  57.     imageView,      // 对应的imageView控件  
  58.     options);       // 与之对应的image显示方式选项  
  59.   
  60. //  4.2 调用loadImage  
  61. //      对于部分DisplayImageOptions对象的设置不起作用  
  62. imageLoader.loadImage(  
  63.         uri,   
  64.         options,   
  65.         new MyImageListener()); //ImageLoadingListener  
  66. class MyImageListener extends SimpleImageLoadingListener{  
  67.   
  68.     @Override  
  69.     public void onLoadingStarted(String imageUri, View view) {  
  70.         imageView.setImageResource(R.drawable.loading);  
  71.         super.onLoadingStarted(imageUri, view);  
  72.     }  
  73.   
  74.     @Override  
  75.     public void onLoadingFailed(String imageUri, View view,  
  76.             FailReason failReason) {  
  77.         imageView.setImageResource(R.drawable.no_pic);  
  78.         super.onLoadingFailed(imageUri, view, failReason);  
  79.     }  
  80.   
  81.     @Override  
  82.     public void onLoadingComplete(String imageUri, View view,  
  83.             Bitmap loadedImage) {  
  84.         imageView.setImageBitmap(loadedImage);  
  85.         super.onLoadingComplete(imageUri, view, loadedImage);  
  86.     }  
  87.   
  88.     @Override  
  89.     public void onLoadingCancelled(String imageUri, View view) {  
  90.         imageView.setImageResource(R.drawable.cancel);  
  91.         super.onLoadingCancelled(imageUri, view);  
  92.     }  
  93.       
  94. }  

3.支持的Uri

[java] view plaincopy
  1. String imageUri = "http://site.com/image.png";      // from Web  
  2. String imageUri = "file:///mnt/sdcard/image.png";   // from SD card  
  3. String imageUri = "content://media/external/audio/albumart/13"; // from content provider  
  4. String imageUri = "assets://image.png";             // from assets  
  5. String imageUri = "drawable://" + R.drawable.image; // from drawables (only images, non-9patch)  

加载drawables下图片,可以通过ImageView.setImageResource(...) 而不是通过上面的ImageLoader.

4.缓冲至手机

默认不能保存缓存,必须通过下面的方式指定

[java] view plaincopy
  1. DisplayImageOptions options = new DisplayImageOptions.Builder()  
  2.         ...  
  3.         .cacheInMemory(true)  
  4.         .cacheOnDisc(true)  
  5.         ...  
  6.         .build();  
  7. ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext())  
  8.         ...  
  9.         .defaultDisplayImageOptions(options)  
  10.         ...  
  11.         .build();  
  12. ImageLoader.getInstance().init(config); // Do it on Application start  
  13.   
  14. ImageLoader.getInstance().displayImage(imageUrl, imageView);    /* 
  15.                                             默认为defaultDisplayImageOptions设定的options对象,此处不用指定options对象 */  

或者通过下面这种方式

[java] view plaincopy
  1. DisplayImageOptions options = new DisplayImageOptions.Builder()  
  2.         ...  
  3.         .cacheInMemory(true)  
  4.         .cacheOnDisc(true)  
  5.         ...  
  6.         .build();  
  7. ImageLoader.getInstance().displayImage(imageUrl, imageView, options); //此处指定options对象  

由于缓存需要在外设中写入数据,故需要添加下面的权限

[html] view plaincopy
  1. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>  

5.OutOfMemoryError

如果OutOfMemoryError错误很常见,可以通过下面的方式设置
(1).减少configuration中线程池的线程数目(.threadPoolSize(...)) 推荐为1 - 5
(2).display options通过.bitmapConfig(Bitmap.Config.RGB_565)设置. Bitmaps in RGB_565 consume 2 times less memory than in ARGB_8888.
(3).使用configuration的memoryCache(new WeakMemoryCache())方法 或者不调用.cacheInMemory()方法
(4).display options通过.imageScaleType(ImageScaleType.IN_SAMPLE_INT) 或者 .imageScaleType(ImageScaleType.EXACTLY)方法
(4).避免使用RoundedBitmapDisplayer,它创建了一个新的ARGB_8888 Bitmap对象

6.内存缓存管理

通过imageLoaderConfiguration.memoryCache([new LruMemoryCache(1)]))对手机内存缓存进行管理

LruMemoryCache

API >= 9默认.it is moved to the head of a queue.

FreqLimitedMemoryCache

当超过缓存大小后,删除最近频繁使用的bitmap

LRULimitedMemoryCache

API < 9 默认.当超过缓存大小后,删除最近使用的bitmap

FIFOLimitedMemoryCache

FIFO rule is used for deletion when cache size limit is exceeded

LargestLimitedMemoryCache

The largest bitmap is deleted when cache size limit is exceeded

WeakMemoryCache

Unlimited cache

7.SDcard缓存管理

通过imageLoaderConfiguration.discCache([new TotalSizeLimitedDiscCache()]))对SD卡缓存进行管理

UnlimitedDiscCache

default The fastest cache, doesn't limit cache size

TotalSizeLimitedDiscCache

Cache limited by total cache size. If cache size exceeds specified limit then file with themost oldest lastusage date will be deleted

FileCountLimitedDiscCache

Cache limited by file count. If file count in cache directory exceeds specified limit then file with the most oldest last usage date will be deleted.

LimitedAgeDiscCache

Size-unlimited cache with limited files' lifetime. If age of cached file exceeds defined limit then it will be deleted from cache.

UnlimitedDiscCache is 30%-faster than other limited disc cache implementations.

http://blog.csdn.net/zimo2013/article/details/9901833

http://mikewang.blog.51cto.com/3826268/1228671