開源項目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。


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