相信做過一兩年android開發(fā)的程序員玩焰,應(yīng)該都使用過UIL庫(Universal-Image-Loader),這是一個(gè)強(qiáng)大的圖片加載庫,支持各種配置篷店,但是這些常用配置往往對(duì)于不用的項(xiàng)目,也幾乎大同小異臭家,本著代碼復(fù)用疲陕,高效開發(fā)業(yè)務(wù)代碼的原則,本文就來基于UIL庫钉赁,做一個(gè)簡(jiǎn)單的封裝蹄殃。
- 首先新建一個(gè)Android Library的module,便于多個(gè)項(xiàng)目共享你踩,然后在這個(gè)module的build.gradle中加入對(duì)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)先級(jí)
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í)例對(duì)象
*/
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) // 針對(duì)不同安卓系統(tǒng)的線程優(yōu)先級(jí)的適配吩谦,加載圖片的線程優(yōu)先級(jí)
.denyCacheImageMultipleSizesInMemory() // 防止加載器緩存多套不同的尺寸到內(nèi)存中
.memoryCache(new WeakMemoryCache()) // 使用弱引用鸳谜,在系統(tǒng)內(nèi)存不足時(shí)回收?qǐng)D片資源
.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);
}
}
}
源碼的注釋寫的很清楚咐扭,至于為什么這么配置圖片加載器對(duì)象和顯示對(duì)象,這是根據(jù)項(xiàng)目中使用的經(jīng)營(yíng)總結(jié)的滑废。
使用也很簡(jiǎn)單蝗肪,當(dāng)然也可以自定義自己的加載器配置和圖形顯示配置,同時(shí)也可以監(jiān)聽圖形加載情況:
ImageLoaderManager.getInstance(Activity.實(shí)例對(duì)象)
.showImage(ivHeaderImage, "http://www.jkfds.com/jrweosdfjk.jpg")
一個(gè)簡(jiǎn)單的封裝蠕趁,UIL庫源碼還是值得多分析的穗慕,里面有很多設(shè)計(jì)思想,最簡(jiǎn)單的比如圖片加載器對(duì)象的DCL妻导,雙檢查單例(這邊在有些情況下IPC多進(jìn)程的應(yīng)用場(chǎng)景需要注意下逛绵,單例失效的問題)圖片加載器配置和圖片顯示配置,對(duì)于這樣需要設(shè)置很多配置信息內(nèi)容屬性的倔韭,可以用構(gòu)建者模式术浪,靈活優(yōu)雅。還可以學(xué)習(xí)到圖片加載的三級(jí)緩存機(jī)制寿酌,以及圖片任務(wù)下載多線程線程池任務(wù)隊(duì)列的處理等等胰苏。