1. 程式人生 > >Universal-Image-Loader的封裝

Universal-Image-Loader的封裝

Universal Image Loade介紹

UIL有很多的優點高度的可定製性,是我使用最多的圖片載入框架,今天就來整理下它的使用以及封裝的方法。

Features:

  • Multithread image loading (async or sync)
  • Wide customization of ImageLoader’s configuration (thread executors, downloader, decoder, memory and disk cache, display image options, etc.)
  • Many customization options for every display image call (stub images, caching switch, decoding options, Bitmap processing and displaying, etc.)
  • Image caching in memory and/or on disk (device’s file system or SD card)
  • Listening loading process (including downloading progress)

特點:

  • 多執行緒影象載入(非同步或同步)
  • ImageLoader配置的廣泛定製(執行緒執行器,下載器,解碼器,記憶體和磁碟快取,顯示影象選項等)
  • 每個顯示影象呼叫的許多自定義選項(存根影象,快取切換,解碼選項,點陣圖處理和顯示等)
  • 記憶體和/或磁碟上的影象快取(裝置的檔案系統或SD卡)
  • 監聽載入過程(包括下載進度)

UIL圖片處理流程:

圖片處理流程

我們的使用步驟:

  1. 搭建UIL使用環境
  2. 瞭解UIL常用的API
  3. 封裝

一、我們首先來看下基礎的UIL怎樣使用

我們要使用之前首先需要獲取到ImageLoader的一個例項:

// 先來獲取到Image Loader的一個例項
ImageLoader imageLoader = ImageLoader.getInstance();//開始是使用預設的配置建立imageLoader

獲取到ImageLoader的例項後就可以進行圖片的載入:

//使用displayImage去載入圖片,圖片地址,要載入的地方
imageLoader.displayImage("url",imageView);

這是最簡單的使用,在這裡還可以新增顯示圖片時的一個Options以及一個載入的監聽

        imageLoader.displayImage("url",imageView,options,new SimpleImageLoadingListener(){
            @Override
            public void onLoadingCancelled(String imageUri, View view) {
                super.onLoadingCancelled(imageUri, view);
            }

            @Override
            public void onLoadingStarted(String imageUri, View view) {
                super.onLoadingStarted(imageUri, view);
            }

            @Override
            public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
                super.onLoadingFailed(imageUri, view, failReason);
            }

            @Override
            public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
                super.onLoadingComplete(imageUri, view, loadedImage);
            }
        });

options的獲取:

//為我們顯示圖片的時候進行一個配置
DisplayImageOptions options = new DisplayImageOptions.Builder().build();

這些都使用的是一個預設的配置項,包括建立的ImageLoader例項,我們可以根據自己需求進行配置。說完基礎的API使用下面介紹下我對UIL的封裝思路。

二、對UIL的封裝

ImageLoaderManager封裝分為三個模組:

  1. 預設引數配置及提供必要的引數介面(方便不需要每次都配置一堆引數)
  2. 提供單例物件對外提供介面(仿照原始碼也以單例模式對外提供這個類的例項)
  3. 對外提供載入圖片API(提供各種對外API供應用層來載入圖片)

在封裝之前我們首先建立一些預設的引數值用於配置

/**
     * 預設的引數值
     */
    //UIL最多可以有多少條執行緒
    private static final int THREAD_COUNT = 4;
    //圖片載入優先順序
    private static final int PROPRITY = 2;
    //UIL最多可以快取多少圖片(硬碟快取大小)
    private static final int DISK_CACHE_SIZE = 50 * 1024;
    //連線的超時時間5s
    private static final int CONNECT_TIME_OUT = 5 * 1000;
    //讀取的超時時間 30s
    private static final int READ_TIME_OUT = 30 * 1000;

下來我們來建立單例模式,用於獲取到此類的物件供外層使用

private static ImageLoader mImageLoader = null;
    //單例模式
    private static ImageLoaderManager mInstance = null;

    public static ImageLoaderManager getmInstance(Context context) {
        //判斷當前單例是否為空
        if (mInstance == null) {
            //為空,建立
            //同步塊,保證不會因為多執行緒而產生多個例項
            synchronized (ImageLoaderManager.class) {
                if (mInstance == null) {
                    //呼叫私有構造方法
                    mInstance = new ImageLoaderManager(context);
                }
            }
        }
        //返回單例
        return mInstance;
    }

下來是單例模式的私有構造方法,以及我們對ImageLoader的配置

/**
  * 單例模式的私有構造方法
  *
  * @param context
  */
    private ImageLoaderManager(Context context) {
        //完成引數的配置
        ImageLoaderConfiguration configuration = new ImageLoaderConfiguration.
                Builder(context)
                .threadPoolSize(THREAD_COUNT)//設定圖片下載執行緒的最大數量
                .threadPriority(Thread.NORM_PRIORITY - PROPRITY)//相對優先順序,裝置效能不同所以獲取對應系統正常的優先順序然後再降級
                .denyCacheImageMultipleSizesInMemory()//防止快取多套尺寸圖片
                .memoryCache(new WeakMemoryCache())//使用弱引用記憶體快取,記憶體不足時會回收圖片
                .diskCacheSize(DISK_CACHE_SIZE)//分配硬碟快取大小
                .diskCacheFileNameGenerator(new Md5FileNameGenerator())//使用Md5命名檔案,起到安全作用
                .tasksProcessingOrder(QueueProcessingType.LIFO)//設定圖片下載順序
                .defaultDisplayImageOptions(getDefultOptions())//預設的圖片載入Option
                .imageDownloader(new BaseImageDownloader(context, CONNECT_TIME_OUT
                        , READ_TIME_OUT))//設定圖片下載器
                .writeDebugLogs()//debug環境下會輸出日誌
                .build();

        //提供配置,初始化
        ImageLoader.getInstance().init(configuration);
        mImageLoader = ImageLoader.getInstance();
    }

配置我們的Options,顯示圖片時的一個配置

/**
  * 實現預設的Options
  *
  * @return
  */
    private DisplayImageOptions getDefultOptions() {
        DisplayImageOptions options = new DisplayImageOptions.Builder()
                .showImageForEmptyUri(R.mipmap.ic_launcher)//在圖片地址為空時
                .showImageOnFail(R.mipmap.ic_launcher)//下載失敗時顯示的圖片
                .cacheInMemory(true)//設定圖片可以快取在記憶體
                .cacheOnDisk(true)
                .bitmapConfig(Bitmap.Config.RGB_565)//設定圖片解碼型別,減少記憶體佔用。使用的圖片解碼型別
                .decodingOptions(new BitmapFactory.Options())//圖片解碼配置(手機OS自帶)
                .build();
        return options;
    }

到這我們的UIL的引數配置都已經換成我們的引數配置,接下來我們實現對外載入圖片方法的封裝

public void displayImage(ImageView imageView, String url,
                             DisplayImageOptions options, ImageLoadingListener listener) {

     if (mImageLoader != null) {
         mImageLoader.displayImage(url, imageView, options, listener);
     }
}

public void displayImage(ImageView imageView, String url, ImageLoadingListener listener) {
     displayImage(imageView, url, null, listener);
}

public void displayImage(ImageView imageView, String url) {
     displayImage(imageView, url, null);
}

這樣我們就完成了基本的封裝

下次我們使用時只需要ImageLoaderManager.getInstance(context).display()然後傳入對應的引數就可以完成圖片的載入。