開發App過程中,免不了要進行網絡請求操作進行資料交換,比如下載下傳圖檔,如果自己寫一個下載下傳圖檔的類進行操作的話,要考慮太多太多内容,必須線程池,記憶體溢出,圖檔磁盤緩存操作,圖檔記憶體緩存操作等等,相當麻煩。好在偉大的開源者們已經寫好了一個比較完美的開源類庫供大家使用Android-Universal-Image-Loader,這個類庫已經被許多知名的軟體所采用,當時我自己用這個開源類庫的時候,百度了一大推,有檢視了官方文檔。現在把記錄寫下來供大家參考。
一、介紹:
Android-Universal-Image-Loader的目的是提供一個功能強大的,靈活的,高度可定制的圖像加載,緩存和顯示工具。它提供了大量的配置選項,并很好地控制圖像加載和緩存。
類庫的特點
l 多線程的圖像加載(同步或異步)
l 靈活的圖像加載配置選項(線程執行,下載下傳,解碼,記憶體和磁盤緩存,圖像顯示選項)
l 自定義每個顯示圖像的配置
l 在記憶體或磁盤上緩存(裝置記憶體或SD卡)
l 監聽加載程序(包括下載下傳進度)
效果圖
二、用法
先來看下引入該類包後,加載圖檔的運作流程圖
從圖中可看出,加載圖檔的時候一共分為三種情況:
(post process Bitmap一步,實際就是對該圖檔進行處理,比如加水印,加圓角等等,該架構沒有給出具體實作,預設為null,如有需要自己可以實作,是以分析的時候可以忽略)
1. 圖檔在記憶體中緩存:直接顯示圖檔。
2. 圖檔在磁盤中緩存:先解碼,再暫時緩存到記憶體中,最後顯示。
3. 圖檔沒有緩存:先下載下傳,再是否緩存到磁盤和記憶體,最後顯示。
(一) Include Library
官網下載下傳依賴jar包,導入工程中libs檔案夾下并添加到工程路徑即可。
(二) 權重限
<manifest>
<!-- Include following permission if you load images from Internet -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- Include following permission if you want to cache images on SD card -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
...
</manifest>
(三)全局配置
全局配置我一般寫個類繼承application,然後在Mainfest檔案中聲明
public class MyApplication extends Application {
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
initImageLoader(getApplicationContext());
}
public static void initImageLoader(Context context){
File cacheDir = StorageUtils.getCacheDirectory(context);
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context)
.memoryCacheExtraOptions(480, 800) // default = device screen dimensions
.diskCacheExtraOptions(480, 800, null)
// .taskExecutor(...)
// .taskExecutorForCachedImages(...)
.threadPoolSize(3) // default
.threadPriority(Thread.NORM_PRIORITY - 2) // default
.tasksProcessingOrder(QueueProcessingType.FIFO) // default
.denyCacheImageMultipleSizesInMemory()
// .memoryCache(new LruMemoryCache(2 * 1024 * 1024))
.memoryCacheSize(2 * 1024 * 1024)
.memoryCacheSizePercentage(13) // default
.diskCache(new UnlimitedDiscCache(cacheDir)) // default
.diskCacheSize(50 * 1024 * 1024)
.diskCacheFileCount(100)
.diskCacheFileNameGenerator(new HashCodeFileNameGenerator()) // default
.imageDownloader(new BaseImageDownloader(context)) // default
// .imageDecoder(new BaseImageDecoder()) // default
.defaultDisplayImageOptions(DisplayImageOptions.createSimple()) // default
.writeDebugLogs()
.build();
// Initialize ImageLoader with configuration.初始化配置
ImageLoader.getInstance().init(config);
}
}
<application
android:name=".base.MyApplication"
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
以上的配置大部分都有預設值,按照自己的需要進行配置,沒必要全部都寫上,現在的顯示配置也是一樣。
(四)顯示配置
顯示配置是具體到每個顯示圖檔任務的配置
DisplayImageOptions options = new DisplayImageOptions.Builder()
.showImageOnLoading(R.drawable.ic_stub) // resource or drawable
.showImageForEmptyUri(R.drawable.ic_empty) // resource or drawable
.showImageOnFail(R.drawable.ic_error) // resource or drawable
.resetViewBeforeLoading(false) // default
.delayBeforeLoading(1000)
.cacheInMemory(false) // default
.cacheOnDisk(false) // default
.preProcessor(...)
.postProcessor(...)
.extraForDownloader(...)
.considerExifParams(false) // default
.imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2) // default
.bitmapConfig(Bitmap.Config.ARGB_8888) // default
.decodingOptions(...)
.displayer(new SimpleBitmapDisplayer()) // default
.handler(new Handler()) // default
.build();
(五)配置完了使用
用預設配置顯示:ImageLoader.getInstance().displayImage(imageUrl, imageView);
用自定義配置顯示:ImageLoader.getInstance().displayImage(imageUrl, imageView,options);
帶監聽事件的顯示:
imageLoader.displayImage(imageUrl, imageView, options, new ImageLoadingListener() {
@Override
public void onLoadingStarted() {
//開始加載的時候執行
}
@Override
public void onLoadingFailed(FailReason failReason) {
//加載失敗的時候執行
}
@Override
public void onLoadingComplete(Bitmap loadedImage) {
//加載成功的時候執行
}
@Override
public void onLoadingCancelled() {
//加載取消的時候執行
}});
帶監聽事件和進度條的顯示:
imageLoader.displayImage(imageUri, imageView, options, new ImageLoadingListener() {
@Override
public void onLoadingStarted(String imageUri, View view) {
...
}
@Override
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
...
}
@Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
...
}
@Override
public void onLoadingCancelled(String imageUri, View view) {
...
}
}, new ImageLoadingProgressListener() {
@Override
public void onProgressUpdate(String imageUri, View view, int current, int total) {
...
}
});
有的文章提出加載本地圖檔也用 ImageLoader.getInstance().displayImage,完全沒有必要。
三、注意事項
1.上述提到的2個權限必須加入,否則會出錯
2.ImageLoaderConfiguration必須配置并且全局化的初始化這個配置ImageLoader.getInstance().init(config); 否則也會出現錯誤提示
3.ImageLoader是根據ImageView的height,width确定圖檔的寬高。
4.如果經常出現OOM
①減少配置之中線程池的大小,(.threadPoolSize).推薦1-5;
②使用.bitmapConfig(Bitmap.config.RGB_565)代替ARGB_8888;
③使用.imageScaleType(ImageScaleType.IN_SAMPLE_INT)或者 try.imageScaleType(ImageScaleType.EXACTLY);
④避免使用RoundedBitmapDisplayer.他會建立新的ARGB_8888格式的Bitmap對象;
⑤使用.memoryCache(new WeakMemoryCache()),不要使用.cacheInMemory();
對該類庫源碼的解析可以參考這篇大神的文章http://blog.csdn.net/xiaanming/article/details/39057201