Universal-Image-Loader這個開源框架又來給咱們造福了,它是一個圖片加載框架,主要強大在於能夠用於網絡等圖片源的加載,而且有多重緩存機制。先給出其項目地址:https://github.com/nostra13/Android-Universal-Image-Loaderjava
1、簡要說明:android
1.多線程下載圖片,圖片能夠來源於網絡,文件系統,項目文件夾assets中以及drawable中等
2.支持隨意的配置ImageLoader,例如線程池,圖片下載器,內存緩存策略,硬盤緩存策略,圖片顯示選項以及其餘的一些配置
3.支持圖片的內存緩存,文件系統緩存或者SD卡緩存
4.支持圖片下載過程的監聽
5.根據控件(ImageView)的大小對Bitmap進行裁剪,減小Bitmap佔用過多的內存
6.較好的控制圖片的加載過程,例如暫停圖片加載,從新開始加載圖片,通常使用在ListView,GridView中,滑動過程當中暫停加載圖片,中止滑動的時候去加載圖片
7.提供在較慢的網絡下對圖片進行加載git
2、配置和使用github
1.新建一個類繼承Application,實現初始化ImageLoader算法
ImageLoader是一個配置方案,主要是一次性的配置項目中的緩存策略,這樣獨立的配置很便於模塊化。緩存
@Override public void onCreate() { // TODO 自動生成的方法存根 super.onCreate(); //經過配置方案來初始化ImageLoader ImageLoader.getInstance().init(ImageLoaderConfiguration configuration);
}
這裏的參數是一個ImageLoaderConfiguration,這個對象能夠設置緩存,緩存路徑等等,下面咱們先獲得一個默認的配置好的對象。網絡
它使用了Build模式,這樣咱們就能夠很方便的來獲得一個默認的配置好的ImageLoaderConfiguration對象多線程
/** * 建立默認的ImageLoader配置參數,這裏建立了一個默認的配置方案 * @return */ private ImageLoaderConfiguration getDefaultConfig() { ImageLoaderConfiguration config = ImageLoaderConfiguration.createDefault(getApplicationContext()); return config; }
固然,ImageLoaderConfiguration有多重選項能夠配置。下面是各類屬性和本身的默認值app
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context) .memoryCacheExtraOptions(480, 800) // default = device screen dimensions .diskCacheExtraOptions(480, 800, CompressFormat.JPEG, 75, null) .taskExecutor(...) .taskExecutorForCachedImages(...) .threadPoolSize(3) // default .threadPriority(Thread.NORM_PRIORITY - 1) // 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();
example:框架
/** * 全部的配置參數舉例 * @return */ private ImageLoaderConfiguration getWholeConfig() { //設置默認的配置,設置緩存,這裏不設置能夠到別的地方設置 DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder() .cacheInMemory(true) .cacheOnDisk(true) .build(); //設置緩存的路徑 File cacheDir = StorageUtils.getOwnCacheDirectory(getApplicationContext(), "imageloader/Cache"); ImageLoaderConfiguration config = new ImageLoaderConfiguration .Builder(getApplicationContext()) .memoryCacheExtraOptions(480, 800) //即保存的每一個緩存文件的最大長寬 .threadPoolSize(3) //線程池內加載的數量 .threadPriority(Thread.NORM_PRIORITY - 2) //解釋:當同一個Uri獲取不一樣大小的圖片,緩存到內存時,只緩存一個。默認會緩存多個不一樣的大小的相同圖片 .denyCacheImageMultipleSizesInMemory() //拒絕緩存多個圖片。 .memoryCache(new WeakMemoryCache()) //緩存策略你能夠經過本身的內存緩存實現 ,這裏用弱引用,缺點是太容易被回收了,不是很好! .memoryCacheSize(2 * 1024 * 1024) //設置內存緩存的大小 .diskCacheSize(50 * 1024 * 1024) //設置磁盤緩存大小 50M .diskCacheFileNameGenerator(new Md5FileNameGenerator()) //將保存的時候的URI名稱用MD5 加密 .tasksProcessingOrder(QueueProcessingType.LIFO) //設置圖片下載和顯示的工做隊列排序 .diskCacheFileCount(100) //緩存的文件數量 .diskCache(new UnlimitedDiskCache(cacheDir)) //自定義緩存路徑 .defaultDisplayImageOptions(defaultOptions) //顯示圖片的參數,默認:DisplayImageOptions.createSimple() .imageDownloader(new BaseImageDownloader(this, 5 * 1000, 30 * 1000)) // connectTimeout (5 s), readTimeout (30 s)超時時間 .writeDebugLogs() //打開調試日誌 .build();//開始構建
return config; }
剛開始別被嚇跑了,其實看起來多,咱們通常只須要知道這是作什麼的,而後根據本身的需求配置便可。
經常使用配置:
/** * 比較經常使用的配置方案 * @return */ private ImageLoaderConfiguration getSimpleConfig() { //設置緩存的路徑 File cacheDir = StorageUtils.getOwnCacheDirectory(getApplicationContext(), "imageloader/Cache"); ImageLoaderConfiguration config = new ImageLoaderConfiguration .Builder(getApplicationContext()) .memoryCacheExtraOptions(480, 800) //即保存的每一個緩存文件的最大長寬 .threadPriority(Thread.NORM_PRIORITY - 2) //線程池中線程的個數 .denyCacheImageMultipleSizesInMemory() //禁止緩存多張圖片 .memoryCache(new LRULimitedMemoryCache(40*1024*1024)) //緩存策略 .memoryCacheSize(50 * 1024 * 1024) //設置內存緩存的大小 .diskCacheFileNameGenerator(new Md5FileNameGenerator()) //緩存文件名的保存方式 .diskCacheSize(200 * 1024 * 1024) //磁盤緩存大小 .tasksProcessingOrder(QueueProcessingType.LIFO) //工做隊列 .diskCacheFileCount(200) //緩存的文件數量 .diskCache(new UnlimitedDiskCache(cacheDir)) //自定義緩存路徑 //.writeDebugLogs() // Remove for release app .build(); return config; }
注:這裏面有多個參數是有待商榷的,本身根據需求配置便可!
在Activity中清除緩存的方法:
//清除緩存 ImageLoader.getInstance().clearDiskCache(); ImageLoader.getInstance().clearMemoryCache();
Manifest.xml 中加入權限,而且配置Application!
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.kale.universalimageloadertest" android:versionCode="1" android:versionName="1.0" > <!-- 訪問internet的權限 --> <uses-permission android:name="android.permission.INTERNET" /> <!-- Include next permission if you want to allow UIL to cache images on SD card --> <!-- 寫入sd卡的權限 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="18" /> <!-- 添加進本身的Application --> <application android:name="com.kale.universalimageloadertest.application.MyApplication" android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="com.kale.universalimageloadertest.UILListActivity"/> </application> </manifest>
MyApplication.JAVA
package com.kale.universalimageloadertest.application; import java.io.File; import android.app.Application; import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiskCache; import com.nostra13.universalimageloader.cache.disc.naming.Md5FileNameGenerator; import com.nostra13.universalimageloader.cache.memory.impl.FIFOLimitedMemoryCache; import com.nostra13.universalimageloader.cache.memory.impl.LRULimitedMemoryCache; import com.nostra13.universalimageloader.cache.memory.impl.WeakMemoryCache; import com.nostra13.universalimageloader.core.DisplayImageOptions; import com.nostra13.universalimageloader.core.ImageLoader; import com.nostra13.universalimageloader.core.ImageLoaderConfiguration; import com.nostra13.universalimageloader.core.assist.QueueProcessingType; import com.nostra13.universalimageloader.core.download.BaseImageDownloader; import com.nostra13.universalimageloader.utils.StorageUtils; /** * @author:Jack Tony * @tips :新建一個MyApplication繼承Application,並在onCreate() * 中建立ImageLoader的配置參數,並初始化到ImageLoader中代碼 * @date :2014-10-15 */ public class MyApplication extends Application{ @Override public void onCreate() { // TODO 自動生成的方法存根 super.onCreate(); //經過配置方案來初始化ImageLoader ImageLoader.getInstance().init(getSimpleConfig()); } /** * 建立默認的ImageLoader配置參數,這裏建立了一個默認的配置方案 * @return */ private ImageLoaderConfiguration getDefaultConfig() { ImageLoaderConfiguration config = ImageLoaderConfiguration .createDefault(getApplicationContext()); return config; } /** * 全部的配置參數舉例 * @return */ private ImageLoaderConfiguration getWholeConfig() { //設置默認的配置,設置緩存,這裏不設置能夠到別的地方設置 DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder() .cacheInMemory(true) .cacheOnDisk(true) .build(); //設置緩存的路徑 File cacheDir = StorageUtils.getOwnCacheDirectory(getApplicationContext(), "imageloader/Cache"); ImageLoaderConfiguration config = new ImageLoaderConfiguration .Builder(getApplicationContext()) .memoryCacheExtraOptions(480, 800) //即保存的每一個緩存文件的最大長寬 .threadPoolSize(3) //線程池內加載的數量 .threadPriority(Thread.NORM_PRIORITY - 2) //解釋:當同一個Uri獲取不一樣大小的圖片,緩存到內存時,只緩存一個。默認會緩存多個不一樣的大小的相同圖片 .denyCacheImageMultipleSizesInMemory() //拒絕緩存多個圖片。 .memoryCache(new WeakMemoryCache()) //緩存策略你能夠經過本身的內存緩存實現 ,這裏用弱引用,缺點是太容易被回收了,不是很好! .memoryCacheSize(2 * 1024 * 1024) //設置內存緩存的大小 .diskCacheSize(50 * 1024 * 1024) //設置磁盤緩存大小 50M .diskCacheFileNameGenerator(new Md5FileNameGenerator()) //將保存的時候的URI名稱用MD5 加密 .tasksProcessingOrder(QueueProcessingType.LIFO) //設置圖片下載和顯示的工做隊列排序 .diskCacheFileCount(100) //緩存的文件數量 .diskCache(new UnlimitedDiskCache(cacheDir)) //自定義緩存路徑 .defaultDisplayImageOptions(defaultOptions) //顯示圖片的參數,默認:DisplayImageOptions.createSimple() .imageDownloader(new BaseImageDownloader(getApplicationContext(), 5 * 1000, 30 * 1000)) // connectTimeout (5 s), readTimeout (30 s)超時時間 .writeDebugLogs() //打開調試日誌 .build();//開始構建 return config; } /** * 比較經常使用的配置方案 * @return */ private ImageLoaderConfiguration getSimpleConfig() { //設置緩存的路徑 File cacheDir = StorageUtils.getOwnCacheDirectory(getApplicationContext(), "imageloader/Cache"); ImageLoaderConfiguration config = new ImageLoaderConfiguration .Builder(getApplicationContext()) .memoryCacheExtraOptions(480, 800) //即保存的每一個緩存文件的最大長寬 .threadPriority(Thread.NORM_PRIORITY - 2) //線程池中線程的個數 .denyCacheImageMultipleSizesInMemory() //禁止緩存多張圖片 .memoryCache(new LRULimitedMemoryCache(50 * 1024 * 1024)) //緩存策略 .memoryCacheSize(50 * 1024 * 1024) //設置內存緩存的大小 .diskCacheFileNameGenerator(new Md5FileNameGenerator()) //緩存文件名的保存方式 .diskCacheSize(200 * 1024 * 1024) //磁盤緩存大小 .tasksProcessingOrder(QueueProcessingType.LIFO) //工做隊列 .diskCacheFileCount(200) //緩存的文件數量 .diskCache(new UnlimitedDiskCache(cacheDir)) //自定義緩存路徑 //.writeDebugLogs() // Remove for release app .build(); return config; } /* ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context) .memoryCacheExtraOptions(480, 800) // default = device screen dimensions .diskCacheExtraOptions(480, 800, CompressFormat.JPEG, 75, null) .taskExecutor(...) .taskExecutorForCachedImages(...) .threadPoolSize(3) // default .threadPriority(Thread.NORM_PRIORITY - 1) // 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(); */ }
Universal-Image-Loader的內存緩存策略
詳細的緩存策略能夠移步:http://blog.csdn.net/xiaanming/article/details/27525741,下方是總結的結果:
1.強引用緩存
LruMemoryCache(這個類就是這個開源框架默認的內存緩存類,緩存的是bitmap的強引用)
好處:滑動時圖片不會容易被清除,體驗好;壞處:容易出現OOM
2.使用強引用和弱引用相結合的緩存有
UsingFreqLimitedMemoryCache(若是緩存的圖片總量超過限定值,先刪除使用頻率最小的bitmap)
LRULimitedMemoryCache(這個也是使用的lru算法,和LruMemoryCache不一樣的是,他緩存的是bitmap的弱引用)
FIFOLimitedMemoryCache(先進先出的緩存策略,當超過設定值,先刪除最早加入緩存的bitmap)
LargestLimitedMemoryCache(當超過緩存限定值,先刪除最大的bitmap對象)
LimitedAgeMemoryCache(當 bitmap加入緩存中的時間超過咱們設定的值,將其刪除)
3.只使用弱引用緩存
WeakMemoryCache(這個類緩存bitmap的總大小沒有限制,惟一不足的地方就是不穩定,緩存的圖片容易被回收掉)
好處:對緩存的bitmap總大小無限制;壞處:使得圖片不穩定,圖片極其容易被回收
注意:不要使用.cacheInMemory();
Universal-Image-Loader的硬盤緩存策略
詳細的硬盤緩存策略能夠移步:http://blog.csdn.net/xiaanming/article/details/27525741,下方是總結的結果:
FileCountLimitedDiscCache(能夠設定緩存圖片的個數,當超過設定值,刪除掉最早加入到硬盤的文件)
LimitedAgeDiscCache(設定文件存活的最長時間,當超過這個值,就刪除該文件)
TotalSizeLimitedDiscCache(設定緩存bitmap的最大值,當超過這個值,刪除最早加入到硬盤的文件)
UnlimitedDiscCache(這個緩存類沒有任何的限制)
在ImageLoaderConfiguration中配置了diskCacheSize和diskCacheFileCount,他就使用的是LruDiscCache,不然使用的是UnlimitedDiscCache
在最新的源碼中還有一個硬盤緩存類能夠配置,那就是LimitedAgeDiscCache,能夠在ImageLoaderConfiguration.diskCache(...)配置
避免OOM
爲了不OOM,能夠修改下面的配置方案:
.memoryCacheExtraOptions(480, 800) //即保存的每一個緩存文件的最大長寬,大小自行配製
.threadPriority(Thread.NORM_PRIORITY - 2) //線程池中線程的個數,通常配置1-5,這裏配的是3
.memoryCache(new LRULimitedMemoryCache(40*1024*1024)) //改變緩存策略,能夠用弱引用
參考自:
http://blog.csdn.net/xiaanming/article/details/26810303
http://blog.csdn.net/xiaanming/article/details/27525741
http://blog.csdn.net/vipzjyno1/article/details/23206387