您的位置:首页 > 移动开发 > Android开发

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

2014-03-05 15:45 211 查看
一、简单说明

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比较简单些,常规工具类,如ImageSizeUtils、StorageUtils等。
二、使用步骤

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。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐