安装UIL
1、添加依赖
- 手动下载JAR包
或者
Gradle
compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
2、Android Manifest
<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>
3、初始化
在Application或Activity中进行初始化
public class MyActivity extends Activity {
@Override
public void onCreate() {
super.onCreate();
// Create global configuration and initialize ImageLoader with this config
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(this)
//初始化加载配置
...
.build();
ImageLoader.getInstance().init(config);
...
}
}
注:一定要记得构造ImageLoaderConfiguration,并传入ImageLoader.init(ImageLoaderConfiguration config)进行初始化,否则会报错。
基本用法
一般用法,异步加载并显示图片
ImageLoader imageLoader = ImageLoader.getInstance(); // Get singleton instance
// Load image, decode it to Bitmap and display Bitmap in ImageView (or any other view
// which implements ImageAware interface)
imageLoader.displayImage(imageUri, imageView);
带回调的loadImage,图片加载完成会返回Bitmap
// Load image, decode it to Bitmap and return Bitmap to callback
imageLoader.loadImage(imageUri, new SimpleImageLoadingListener() {
@Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
// Do whatever you want with Bitmap
}
});
//ImageLoadingListener全部回调方法
public interface ImageLoadingListener {
void onLoadingStarted(String var1, View var2);
void onLoadingFailed(String var1, View var2, FailReason var3);
void onLoadingComplete(String var1, View var2, Bitmap var3);
void onLoadingCancelled(String var1, View var2);
}
同步加载图片,会阻塞所在线程,知道返回Bitmap
// Load image, decode it to Bitmap and return Bitmap synchronously
ImageSize targetSize = new ImageSize(80, 50); // result Bitmap will be fit to this size
Bitmap bmp = imageLoader.loadImageSync(imageUri, targetSize, options);
以上方法最终都会调用到下面这个方法,通过参数可以看到,还可以定义显示尺寸和进度监听器(监听图片显示进度,配合产生图片上进度条的效果)
displayImage(String uri, ImageAware imageAware, DisplayImageOptions options, ImageSize targetSize, ImageLoadingListener listener, ImageLoadingProgressListener progressListener)
//进度监听器
public interface ImageLoadingProgressListener {
void onProgressUpdate(String var1, View var2, int var3, int var4);
}
整体配置参数(ImageLoaderConfiguration)
以下是ImageLoaderConfiguration所有的可配置项,并且是默认配置参数
// DON'T COPY THIS CODE TO YOUR PROJECT! This is just example of ALL options using.
// See the sample project how to use ImageLoader correctly.
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 UnlimitedDiskCache(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();
图片显示配置参数(DisplayImageOptions)
以下是DisplayImageOptions所有的可配置项,并且是默认配置参数
// DON'T COPY THIS CODE TO YOUR PROJECT! This is just example of ALL options using.
// See the sample project how to use ImageLoader correctly.
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();
如果不自定义DisplayImageOptions,会在ImageLoaderConfiguration配置里面使用默认实现。以上两个类完成了所有的UIL参数配置,都采用了建造者模式(Builder)解决大量的参数问题,其中ImageLoaderConfiguration是强制要实现并且显式注入ImageLoader。
常用特性
1、开启缓存
缓存默认不开启,缓存参数在DisplayImageOptions 进行配置
// Create default options which will be used for every
// displayImage(...) call if no options will be passed to this method
DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder()
...
.cacheInMemory(true)//开启内存缓存
.cacheOnDisk(true)//开启磁盘缓存
...
.build();
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext())
...
.defaultDisplayImageOptions(defaultOptions)//注入自己的图片显示配置
...
.build();
ImageLoader.getInstance().init(config); // Do it on Application start
2、Bitmap大小的确定
一般用layout_width、layout_height 或 maxWidth、maxHeight来计算Bitmap的大小。
3、OOM的解决办法
- 先关闭内存缓存,如果还有OOM发生,则说明发生了内存泄漏,以下几点可以帮助解决内存泄漏
- 减少线程池的大小.threadPoolSize(…),建议大小1-5
- .bitmapConfig(Bitmap.Config.RGB_565),改变图片编码为RGB_565,比RGB_8888消耗更小内存
- .imageScaleType(ImageScaleType.EXACTLY),改变缩放模式为严格模式
- .diskCacheExtraOptions(480, 320, null),设置磁盘缓存的图片为固定大小
4、内存缓存可选项
- 默认使用强引用的内存缓存
- LruMemoryCache (Least recently used bitmap is deleted when cache size limit is exceeded) - Used by default
- 其他缓存方式
- UsingFreqLimitedMemoryCache (Least frequently used bitmap is deleted when cache size limit is exceeded)
- LRULimitedMemoryCache (Least recently used bitmap is deleted when cache size limit is exceeded)
- FIFOLimitedMemoryCache (FIFO rule is used for deletion when cache size limit is exceeded)(使用FIFO的方式进行置换)
- LargestLimitedMemoryCache (The largest bitmap is deleted when cache size limit is exceeded)(删除占用内存最大的)
- LimitedAgeMemoryCache (Decorator. Cached object is deleted when its age exceeds defined value)(删除缓存时间最久的)
- 弱引用缓存
- WeakMemoryCache (Unlimited cache)(容量不限)
5、磁盘缓存可选项
- UnlimitedDiscCache (The fastest cache, doesn’t limit cache size)(默认,没有容量限制)
- LruDiskCache (Cache limited by total cache size and/or by file count. If cache size exceeds specified limit then least-recently used file will be deleted)(LRU置换)
- LimitedAgeDiscCache (Size-unlimited cache with limited files’ lifetime. If age of cached file exceeds defined limit then it will be deleted from cache.)(删除时间最久的)
6、图片显示方式
在DisplayImageOptions.displayer(…)方法配置,默认有以下实现
- RoundedBitmapDisplayer (Displays bitmap with rounded corners)(圆形)
- FadeInBitmapDisplayer (Displays image with “fade in” animation)(淡入淡出动画)
7、滑动事件监听
boolean pauseOnScroll = false; // or true
boolean pauseOnFling = true; // or false
PauseOnScrollListener listener = new PauseOnScrollListener(imageLoader, pauseOnScroll, pauseOnFling);
listView.setOnScrollListener(listener);
8、其他
- If you see in logs some strange supplement at the end of image URL (eg.http://anysite.com/images/image.png_230x460) then it doesn’t mean this URL is used in requests. This is just “URL + target size”, also this is key for Bitmap in memory cache. This postfix (_230x460) is NOT used in requests.
- ImageLoader总是保持图片的纵横比
主要类与方法
ImageLoader | | - init(ImageLoaderConfiguration) | - isInited() | - displayImage(...) | - loadImage(...) | - loadImageSync(...) | - getMemoryCache() | - clearMemoryCache() | - getDiskCache() | - clearDiskCache() | - denyNetworkDownloads(boolean) | - handleSlowNetwork(boolean) | - setDefaultLoadingListener(...) | - pause() | - resume() | - stop() | - destroy() | - getLoadingUriForView(ImageView) | - cancelDisplayTask(ImageView) ImageAware | | - getId() | - getWidth() | - getHeight() | - getScaleType() | - getWrappedView() | - isCollected() | - setImageDrawable(Drawable) | - setImageBitmap(Bitmap) MemoryCacheUtil | | - findCachedBitmapsForImageUri(...) | - findCacheKeysForImageUri(...) | - removeFromCache(...) DiskCacheUtil | | - findInCache(...) | - removeFromCache(...) StorageUtils | | - getCacheDirectory(Context) | - getIndividualCacheDirectory(Context) | - getOwnCacheDirectory(Context, String) ImageScaleType | NONE | IN_SAMPLE_POWER_OF_2 | IN_SAMPLE_INT | EXACTLY | EXACTLY_STRETCHED QueueProcessingType | FIFO | LIFO FailReason.FailType | IO_ERROR | DECODING_ERROR | NETWORK_DENIED | OUT_OF_MEMORY | UNKNOWN ImageLoadingListener | | | - onLoadingStarted(String, View) | | - onLoadingFailed(String, View, FailReason) | | - onLoadingComplete(String, View, Bitmap) | | - onLoadingCancelled(String, View) |---- SimpleImageLoadingListener ImageDownloader |---- BaseImageDownloader |---- NetworkDeniedImageDownloader |---- SlowNetworkImageDownloader ImageDecoder |---- BaseImageDecoder BitmapDisplayer |---- SimpleBitmapDisplayer |---- FadeInBitmapDisplayer |---- RoundedBitmapDisplayer |---- RoundedVignetteBitmapDisplayer DiskCache |---- BaseDiscCache |---- UnlimitedDiscCache |---- LruDiskCache |---- LimitedAgeDiscCache MemoryCacheAware |---- BaseMemoryCache | |---- WeakMemoryCache | |---- LimitedMemoryCache | |---- UsingFreqLimitedMemoryCache | |---- LRULimitedMemoryCache | |---- LargestLimitedMemoryCache | |---- FIFOLimitedMemoryCache |---- LimitedAgeMemoryCache |---- LruMemoryCache FileNameGenerator |---- HashCodeFileNameGenerator |---- Md5FileNameGenerator PauseOnScrollListener
任务流图
任务流图中的每一步都有自己的接口(在图片底部)来负责这部分的任务。大部分接口(除了BitmapProcessor)都拥有默认的实现从左到右依次是BaseImageDowloader、UnlimitedDiscCache、BaseImageDecoder、LruMemoryCache、SimpleBitmapDisplayer