开源项目Android-Universal-Image-Loader 解析

一、简单说明

       Android-Universal-Image-Loader是一个开源的UI组件程序,该项目的目的是提供一个可重复使用的仪器为异步图像加载,缓存和显示。这个开源的东西,比我想象的要强的的多,不但实现合理的图片缓存、异步加载,还可以实现线程池的大小,HTTP选项,内存和光盘高速缓存,显示图像等设置。

       其默认的缓存目录是mnt/sdcard/Android/data/your project/下,因为没有提供接口,所以想修改只能改其源代码。

1.到https://github.com/nostra13/Android-Universal-Image-Loader把源代码拿下来
2.导入library项目,修改com.nostra13.universalimageloader.utils.StorageUtils这个类,getExternalCacheDir(Context context)这个方法返回的就是缓存图片目录,getCacheDirectory(Context context)是真正返回缓存目录的方法。

代码目录:

universalimageloader的包结构非常清晰。

  (1)cache主要是磁盘缓存及内存缓存预定的接口和常规实现类,包含的算法较多,如FIFO算法、LRU算法等。
  (2)core是整个ImageLoader的核心包,图片下载、适配显示,并向上层应用提供各种接口,默认模板,还包括很多关键枚举类、工具类。
  (3)utils比较简单些,常规工具类,如ImageSizeUtilsStorageUtils等。


二、使用步骤

1、初始化

    使用该项目前要在Application中初始化:

public class IssAppContext extends Application {
    @Override
    public void onCreate() {
        super.onCreate();

        ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(
                getApplicationContext()).threadPriority(Thread.NORM_PRIORITY - 2)
                .denyCacheImageMultipleSizesInMemory()
                .discCacheFileNameGenerator(new Md5FileNameGenerator())
                .tasksProcessingOrder(QueueProcessingType.LIFO).writeDebugLogs() 
                .build();
        // Initialize ImageLoader with configuration.
        ImageLoader.getInstance().init(config);
    }
}

2、获得ImageLoader对象,设置图片加载属性

        imageLoader = ImageLoader.getInstance();
        options = new DisplayImageOptions.Builder().resetViewBeforeLoading(true).cacheOnDisc(true)
                .imageScaleType(ImageScaleType.EXACTLY).bitmapConfig(Bitmap.Config.RGB_565)
                .considerExifParams(true).build();

 图片加载属性设置详解:

          //设置图片在下载期间显示的图片
            showStubImage(R.drawable.ic_launcher)
            
            //设置图片Uri为空或是错误的时候显示的图片
            showImageForEmptyUri(R.drawable.ic_empty)
            
            //设置图片加载/解码过程中错误时候显示的图片
            showImageOnFail(R.drawable.ic_error)
            
            //设置图片在下载前是否重置,复位
            resetViewBeforeLoading()
            
            //设置下载的图片是否缓存在内存中
            cacheInMemory()
            
            //设置下载的图片是否缓存在SD卡中
            cacheOnDisc()
            
            //设置图片的解码类型
            bitmapConfig(Bitmap.Config.RGB_565)
            
            //设置图片的解码配置
            decodingOptions(android.graphics.BitmapFactory.Options decodingOptions)
            
            //设置图片下载前的延迟
            delayBeforeLoading(int delayInMillis) 
            
            //设置额外的内容给ImageDownloader
            extraForDownloader(Object extra)
            
            //设置图片加入缓存前,对bitmap进行设置
            preProcessor(BitmapProcessor preProcessor)
            
            //设置显示前的图片,显示后这个图片一直保留在缓存中
            postProcessor(BitmapProcessor postProcessor) 
            
    /**
    * 设置图片以如何的编码方式显示 imageScaleType(ImageScaleType imageScaleType)
    * EXACTLY :图像将完全按比例缩小的目标大小
    * EXACTLY_STRETCHED:图片会缩放到目标大小完全 IN_SAMPLE_INT:图像将被二次采样的整数倍
    * IN_SAMPLE_POWER_OF_2:图片将降低2倍,直到下一减少步骤,使图像更小的目标大小
    *  NONE:图片不会调整
    */
    imageScaleType( imageScaleType) 

/**    * 设置图片的显示方式 默认值-    * DefaultConfigurationFactory.createBitmapDisplayer()    *    * @param displayer    *            RoundedBitmapDisplayer(int roundPixels)设置圆角图片    *            FakeBitmapDisplayer()这个类什么都没做    *            FadeInBitmapDisplayer(int durationMillis)设置图片渐显的时间    *             SimpleBitmapDisplayer()正常显示一张图片     */

  displayer(new RoundedBitmapDisplayer(20))

 

/**   * 你可以设置你自己实现的内存缓存   */

 memoryCache(new LruMemoryCache(2 * 1024 * 1024))

  /**    * 为位图最大内存缓存大小(以字节为单位),默认值,可用应用程序内存的1/8    * 注意:如果你使用这个方法,那么LruMemoryCache将被用作内存缓存。    * 您可以使用memoryCache(MemoryCacheAware)方法来设置自己的MemoryCacheAware的实现。     */

  memoryCacheSize(2 * 1024 * 1024)    /**   * 当同一个Uri获取不同大小的图片,缓存到内存时,只缓存一个。默认会缓存多个不同的大小的相同图片   */

  denyCacheImageMultipleSizesInMemory()    /**   * 设置本地图片缓存 也可以设置你自己实现 盘缓存必需实现 DiscCacheAware接口   * 类型(在com.nostra13.universalimageloader.cache.disc.impl包下能找到如下的类):   * FileCountLimitedDiscCache(File cacheDir, int maxFileCount):设置缓存路径和缓存文件的数量,超过数量后,old将被删除   *   * FileCountLimitedDiscCache(File cacheDir,FileNameGenerator fileNameGenerator,int maxFileCount):第二个参数是通过图片的url生成的 唯一文件名。   *   * LimitedAgeDiscCache(File cacheDir, FileNameGenerator fileNameGenerator, long maxAge) :第二个参数同上   *   * LimitedAgeDiscCache(File cacheDir, long maxAge):maxAge为定义的时间,超过时间后,图片将被删除   *   * TotalSizeLimitedDiscCache(File cacheDir, FileNameGenerator fileNameGenerator, int maxCacheSize) :第二个参数同上   *   * TotalSizeLimitedDiscCache(File cacheDir, int maxCacheSize) :定义缓存的大小,如超过了,就会删除old图片。 UnlimitedDiscCache(File cacheDir) :缓存没有限制   *   * UnlimitedDiscCache(File cacheDir, FileNameGenerator fileNameGenerator):第二个参数同上   */

  discCache(new FileCountLimitedDiscCache(new File("/sdcard/cache"), 100))//

 /**   * 设置缓存的大小(以字节为单位)默认:本地缓存是不限制大小   * 注意:如果你使用这个方法,那么TotalSizeLimitedDiscCache将被用作磁盘缓存   * 您可以使用discCache(DiscCacheAware)DiscCacheAware引入自己的实现方法   *   * @param maxCacheSize大小   */

  discCacheSize(10*1024*1024)

  /**      * 设置图片保存到本地的参数      * @param maxImageWidthForDiscCache 保存的最大宽度      * @param maxImageHeightForDiscCache 保存的最大高度      * @param compressFormat    保存的压缩格式      * @param compressQuality 提示压缩的程度,有0-100.想png这种图片无损耗,就不必设置了      * @param BitmapProcessor 处理位图,可以更改原来的位图,实现必须是线程安全的。      */

   discCacheExtraOptions(100,10,android.graphics.Bitmap.CompressFormat.JPEG,0, null )

  /**   * 设置缓存文件的数量   * @param maxFileCount数量   */

  discCacheFileCount(100)

 /**   * .taskExecutor(Executor executor) 添加个线程池,进行下载   *   * @param executor   *            线程池   *            如果进行了这个设置,那么threadPoolSize(int),threadPriority(   *            int),tasksProcessingOrder(QueueProcessingType)   *            将不会起作用   */   taskExecutor(Executor executor)  /**   * 设置缓存文件的名字   *   * @param fileNameGenerator   *            discCacheFileNameGenerator(FileNameGenerator   *            fileNameGenerator) 参数fileNameGenerator:   *            HashCodeFileNameGenerator   *            ():通过HashCode将url生成文件的唯一名字   *            Md5FileNameGenerator():通过Md5将url生产文件的唯一名字   */

  discCacheFileNameGenerator(new Md5FileNameGenerator())    /**   * 设置用于显示图片的线程池大小   * @param threadPoolSize   */

threadPoolSize(5)//      /**   * 设置线程的优先级   * @param threadPriority   */

threadPriority(Thread.MIN_PRIORITY + 3)

 /**   * tasksProcessingOrder(QueueProcessingType tasksProcessingType)   * 设置图片下载和显示的工作队列排序   *   * @param tasksProcessingType   */

 

tasksProcessingOrder(QueueProcessingType.LIFO)

 

属性还真不少,不过常用的也就那几个,如果有特殊需求就根据相应的属性进行设置。

3、显示图片

       来分别看几种显示的方式:

    // 将图片显示任务增加到执行池,图片将被显示到ImageView当轮到此ImageView   
     imageLoader.displayImage(imageUrls[position], imageView, options);  

      渐变显示

        private ImageLoadingListener animateFirstListener = new AnimateFirstDisplayListener();
	/**
	 * 显示图片
	 * 参数1:图片url
	 * 参数2:显示图片的控件
	 * 参数3:显示图片的设置
	 * 参数4:监听器
	 */
	imageLoader.displayImage(imageUrls[position], holder.image, options, animateFirstListener);

	
	/**
	 * 图片加载第一次显示监听器
	 * @author Administrator
	 *
	 */
	private static class AnimateFirstDisplayListener extends SimpleImageLoadingListener {
		
		static final List<String> displayedImages = Collections.synchronizedList(new LinkedList<String>());

		@Override
		public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
			if (loadedImage != null) {
				ImageView imageView = (ImageView) view;
				// 是否第一次显示
				boolean firstDisplay = !displayedImages.contains(imageUri);
				if (firstDisplay) {
					// 图片淡入效果
					FadeInBitmapDisplayer.animate(imageView, 500);
					displayedImages.add(imageUri);
				}
			}
		}
	}

   再加一种在html中加载图片的方法

  imageLoader.loadImage(img.getImgSrc(), options, new SimpleImageLoadingListener() {

                @Override
                public void onLoadingStarted(String imageUri, View view) {
                    // TODO Auto-generated method stub
                    super.onLoadingStarted(imageUri, view);
                }

                @Override
                public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
                    // TODO Auto-generated method stub
                    super.onLoadingFailed(imageUri, view, failReason);
                }

                @Override
                public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
                    LogUtil.d(TAG, "webview图片onLoadingComplete");
                    if (AppContext.WEB_DESDROYED) {
                        return;
                    }
                    if (img != null) {

                        String url = "file:///"
                                + DiscCacheUtils.findInCache(img.getImgSrc(),
                                        imageLoader.getDiscCache());

                        try {
                            if (webView != null && img != null && img.getImgId() != null
                                    && !TextUtils.isEmpty(img.getImgId())) {
                                webView.loadUrl("javascript:bookSotre1.bookSotreReplace('"
                                        + img.getImgId() + "','" + url + "')");
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }

      到这差不多了,剩下的就是布局和权限,别忘了添加。以后凡是用到图片加载的项目我建议用这个开源工具,会省去很多事,关键可以避免让人头疼的OOM。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章