圖片加載功能封裝----基于UIL庫的封裝

相信做過一兩年android開發(fā)的程序員,應(yīng)該都使用過UIL庫(Universal-Image-Loader),這是一個(gè)強(qiáng)大的圖片加載庫,支持各種配置,但是這些常用配置往往對于不用的項(xiàng)目,也幾乎大同小異,本著代碼復(fù)用,高效開發(fā)業(yè)務(wù)代碼的原則,本文就來基于UIL庫,做一個(gè)簡單的封裝。


  • 首先新建一個(gè)Android Library的module,便于多個(gè)項(xiàng)目共享,然后在這個(gè)module的build.gradle中加入對UIL庫的依賴:
dependencies {
    ...
    compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
}

當(dāng)然重要的兩個(gè)權(quán)限也別忘記了:

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  • 然后新建一個(gè)類ImageLoaderManager
/**
 * @author Jerry
 * 圖片加載管理,基于UIL庫
 */
public class ImageLoaderManager {
    // 同時(shí)最大的圖片線程加載數(shù)
    public static final int THEAD_COUNT = 5;
    // 圖片加載優(yōu)先級
    public static final int PRIORITY = 5;
    // 磁盤緩存大小,50M
    public static final int DISK_CACHE_SIZE = 50 * 1024 * 1024;
    // 圖片加載連接超時(shí)
    public static final int CONNECT_TIME_OUT = 5 * 1000;
    // 圖片加載IO讀取超時(shí)
    public static final int READ_TIME_OUT = 5 * 1000;

    private static ImageLoader sImageLoader = null;
    private static ImageLoaderManager sInstance = null;

    /**
     * double check,單例
     * @return 實(shí)例對象
     */
    public static ImageLoaderManager getInstance(Context context) {
        if (sInstance == null){
            synchronized (ImageLoaderManager.class){
                if (sInstance == null){
                    sInstance = new ImageLoaderManager(context.getApplicationContext());
                }
            }
        }
        return sInstance;
    }

    private ImageLoaderManager(Context context) {
        ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context)
                .threadPoolSize(THEAD_COUNT)    // 加載圖片線程池中最大的線程數(shù)
                .threadPriority(Thread.NORM_PRIORITY - PRIORITY) // 針對不同安卓系統(tǒng)的線程優(yōu)先級的適配,加載圖片的線程優(yōu)先級
                .denyCacheImageMultipleSizesInMemory()  // 防止加載器緩存多套不同的尺寸到內(nèi)存中
                .memoryCache(new WeakMemoryCache()) // 使用弱引用,在系統(tǒng)內(nèi)存不足時(shí)回收圖片資源
                .diskCacheSize(DISK_CACHE_SIZE) // 磁盤緩存大小
                .diskCacheFileNameGenerator(new Md5FileNameGenerator()) // 使用md5來命名緩存的磁盤圖片文件
                .tasksProcessingOrder(QueueProcessingType.LIFO) // 圖片加載下載的順序,后進(jìn)先出算法
                .defaultDisplayImageOptions(getDefaultDisplayOptions()) // 默認(rèn)的圖片顯示配置器
                .imageDownloader(new BaseImageDownloader(context,
                        CONNECT_TIME_OUT, READ_TIME_OUT))   // 設(shè)置圖片下載器
                .writeDebugLogs()   // debug模式下打印出日志
                .build();
        sImageLoader = ImageLoader.getInstance();
        sImageLoader.init(config);
    }

    private DisplayImageOptions getDefaultDisplayOptions() {
        return new DisplayImageOptions.Builder()
                .showImageForEmptyUri(R.drawable.jsdk_img_error)    // 圖片加載地址為空的時(shí)候顯示的圖片
                .showImageOnFail(R.drawable.jsdk_img_error)         // 圖片加載失敗的時(shí)候顯示的圖片
                .cacheInMemory(true)                                // 設(shè)置圖片可以緩存到內(nèi)存
                .cacheOnDisk(true)                                  // 設(shè)置圖片可以緩存到磁盤
                .bitmapConfig(Bitmap.Config.ARGB_4444)              // 設(shè)置圖片顯示的渲染色彩的質(zhì)量,減小圖片占用內(nèi)存
                .decodingOptions(new BitmapFactory.Options())       // 使用系統(tǒng)默認(rèn)的解碼配置
                .build();
    }

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

    public void showImage(ImageView imageView, String url, ImageLoadingListener loadingListener){
        showImage(imageView, url, null, loadingListener);
    }

    /**
     * 加載顯示圖片
     * @param imageView         圖片控件
     * @param url               圖片地址
     * @param opts              顯示配置
     * @param listener          加載監(jiān)聽回調(diào)
     */
    public void showImage(ImageView imageView, String url, DisplayImageOptions opts,
                          ImageLoadingListener listener){
        if (sImageLoader != null) {
            sImageLoader.displayImage(url, imageView, opts, listener);
        }
    }
}

源碼的注釋寫的很清楚,至于為什么這么配置圖片加載器對象和顯示對象,這是根據(jù)項(xiàng)目中使用的經(jīng)營總結(jié)的。
使用也很簡單,當(dāng)然也可以自定義自己的加載器配置和圖形顯示配置,同時(shí)也可以監(jiān)聽圖形加載情況:

ImageLoaderManager.getInstance(Activity.實(shí)例對象)
          .showImage(ivHeaderImage, "http://www.jkfds.com/jrweosdfjk.jpg")

一個(gè)簡單的封裝,UIL庫源碼還是值得多分析的,里面有很多設(shè)計(jì)思想,最簡單的比如圖片加載器對象的DCL,雙檢查單例(這邊在有些情況下IPC多進(jìn)程的應(yīng)用場景需要注意下,單例失效的問題)圖片加載器配置和圖片顯示配置,對于這樣需要設(shè)置很多配置信息內(nèi)容屬性的,可以用構(gòu)建者模式,靈活優(yōu)雅。還可以學(xué)習(xí)到圖片加載的三級緩存機(jī)制,以及圖片任務(wù)下載多線程線程池任務(wù)隊(duì)列的處理等等。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容