標籤:android-universal-im android圖片 imageview
開發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 {@Overridepublic void onCreate() {// TODO Auto-generated method stubsuper.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
Android-Universal-Image-Loader 圖片非同步載入類庫的使用