转自:http://blog.csdn.net/xiaanming/article/details/26810303
一、简介
相比上一篇来说,这个Universal-Image-Loader太大了。它功能强大,可扩展性好,高度可定制。
特征:
1)多线程下载图片,图片可来源于网络,文件系统,项目文件夹assets及drawable中等。
2)支持随意的配置ImageLoader,例如线程池,图片下载器,内存缓存策略,图片显示选项及其他一些配置。
3)支持图片的内存缓存,文件系统缓存或SD卡缓存。
4)支持图片下载过程的监听。
5)根据ImageView控件大小对Bitmap进行裁剪,减少Bitmap占用过多的内存。
6)较好的控制图片的加载过程,例如暂停图片加载,重新开始加载图片,一般使用ListView,GridView中,滑动过程中暂停加载图片,停止滑动的时候去加载图片。
7)提供在较慢的网络下对图片进行加载。
二、下载地址和支持版本
下载地址:https://github.com/nostra13/Android-Universal-Image-Loader
支持版本:2.0+
三、加载网络图片用法
1、下载JAR并导入到libs。
2、声明网络权限和访问SD卡权限。
3、新建一个MyApplication继承Application或新建一个Activity继承Activity,在onCreate()中配置ImageLoader的参数,并初始化到代码中。
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
//创建默认的ImageLoader配置参数
ImageLoaderConfiguration configuration = ImageLoaderConfiguration
.createDefault(this);
//Initialize ImageLoader with configuration.
ImageLoader.getInstance().init(configuration);
}
}
DisplayImageOptions对每个显示任务来说是局部的。通过ImageLoader.displayImage()调用。
ImageLoaderConfiguration是图片加载器ImageLoader的配置参数,每个应用设置一个全局的实例即可。上面是创建了一个默认的ImageLoaderConfigurations,当然也可以自己设置ImageLoaderConfigurations。
// 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 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();
4、加载图片
注意:显示图片时最好不要用ImageLoader,而是使用ImageView.setImageResource()
final ImageView mImageView = (ImageView) findViewById(R.id.image);
String imageUrl = "https://lh6.googleusercontent.com/-55osAWw3x0Q/URquUtcFr5I/AAAAAAAAAbs/rWlj1RUKrYI/s1024/A%252520Photographer.jpg";
//显示图片的配置
DisplayImageOptions options = new DisplayImageOptions.Builder()
.showImageOnLoading(R.drawable.ic_stub)
.showImageOnFail(R.drawable.ic_error)
.cacheInMemory(true)
.cacheOnDisk(true)
.bitmapConfig(Bitmap.Config.RGB_565)
.build();
ImageLoader.getInstance().displayImage(imageUrl, mImageView, options);
图片显示的配置选项中,添加了一个图片加载中ImageView显示的图片,及图片加载出现错误时显示的图片。而且displayImage()会自动根据控件大小和imageScaleType来裁剪图片。修改下MyApplication,开启log打印:
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
//创建默认的ImageLoader配置参数
ImageLoaderConfiguration configuration = new ImageLoaderConfiguration.Builder(this)
.writeDebugLogs() //打印log信息
.build();
//Initialize ImageLoader with configuration.
ImageLoader.getInstance().init(configuration);
}
}
5、打印log(可有可无)
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
//创建默认的ImageLoader配置参数
ImageLoaderConfiguration configuration = new ImageLoaderConfiguration.Builder(this)
.writeDebugLogs() //打印log信息
.build();
//Initialize ImageLoader with configuration.
ImageLoader.getInstance().init(configuration);
}
}
6、加载图片时,显示图片下载进度。
只需在displayImage()中传入ImageLoadingProgressListener接口就行了。
imageLoader.displayImage(imageUrl, mImageView, options, new SimpleImageLoadingListener(), new ImageLoadingProgressListener() {
@Override
public void onProgressUpdate(String imageUri, View view, int current,
<span style="white-space:pre"> </span>int total) {
}
});
由于displayImage()中带ImageLoadingProgressListener参数的方法都有带ImageLoadingListener参数,所以这里new一个SimpleImageLoadingListener,然后就可在回调方法onProgressUpdate()得到图片的加载进度。
四、加载其他来源图片
只需将url稍加改动即可,下面是加载文件系统的图片
//显示图片的配置
DisplayImageOptions options = new DisplayImageOptions.Builder()
.showImageOnLoading(R.drawable.ic_stub)
.showImageOnFail(R.drawable.ic_error)
.cacheInMemory(true)
.cacheOnDisk(true)
.bitmapConfig(Bitmap.Config.RGB_565)
.build();
final ImageView mImageView = (ImageView) findViewById(R.id.image);
String imagePath = "/mnt/sdcard/image.png";
String imageUrl = Scheme.FILE.wrap(imagePath);
// String imageUrl = "https://img-my.csdn.net/uploads/201309/01/1378037235_7476.jpg";
imageLoader.displayImage(imageUrl, mImageView, options);
当图片来源于Content Provider,drawable,assets中,使用也非常简单,只需给每个图片源加上Schema包裹起来(Content Provider除外),然后当做图片的url传递到imageLoader中:
//图片来源于Content provider
String contentprividerUrl = "content://media/external/audio/albumart/13";
//图片来源于assets
String assetsUrl = Scheme.ASSETS.wrap("image.png");
//图片来源于
String drawableUrl = Scheme.DRAWABLE.wrap("R.drawable.image");
五、GridView、ListView加载图片
当快速滚动时,希望停止加载图片,而在GridView、ListView停止滑动时加载当前界面的图片。这个框架也提供了这个功能,使用起来也简单,它提供了PauseOnScrollListener这个类来控制ListView、GridView滑动过程中停止加载图片:
listView.setOnScrollListener(new PauseOnScrollListener(imageLoader, pauseOnScroll, pauseOnFling));
gridView.setOnScrollListener(new PauseOnScrollListener(imageLoader, pauseOnScroll, pauseOnFling));
第一个参数是图片加载对象;第二个是控制是否在滑动过程中加载图片,如果需要暂停传true即可;第三个参数控制猛的滑动界面时图片是否加载。
六、OOM问题
这个框架产生OOM的概率比较小,并不保证OOM问题永不发生。这个框架对OOM做了简单的crash,保证我们的程序遇到OOM而不被crash掉,但如果我们使用该框架经常发生OOM,该怎么去改善呢?
1、减少线程池中线程的个数。在ImageLoaderConfiguration中的(.threadPoolSize)中配置,推荐1-5。
2、在DisplayImageOptions选项中配置bitmapConfig为Bitmap.Config.RGB_565 ,因为默认是ARGB_8888,使用RGB_565会比ARGB_8888少消耗2倍内存。
3、在ImageLoaderConfiguration中配置图片的内存缓存为memoryCache(new WeakMemoryCache())或者不使用内存缓存。
4、在DisplayImageOptions选项中设置.imageScaleType(ImageScaleType.IN_SAMPLE_INT)或者imageScaleType(ImageScale.EXACTY)
七、题外话
使用这个框架时尽量使用displayImage()去加载图片,loadImage()是将图片对象回调到ImageLoadingListener接口的onLoadingComplete()中,需要手动设置到ImageView上。displayImage()中,对ImageView对象使用的是弱引用,方便垃圾回收器回收ImageView对象,如果我们加载固定大小的图片时,使用loadImage()需要传递一个ImageSize对象,而displayImage()会根据ImageView对象的测量值,或者android:layout_width和android:layout_height设定的值,或者android:maxWidth或android:maxHeight设定的值来裁剪图片。