https://github.com/nostra13/Android-Universal-Image-Loader

 

 

ImageLoader作用

1.多线程下载图片,图片可以来源于网络,文件系统,项目文件夹assets中以及drawable中
2.支持图片的内存缓存,文件系统缓存或者SD卡缓存
3.支持图片下载过程的监听
4.根据控件(ImageView)的大小对Bitmap进行裁剪,减少Bitmap占用过多的内存


加载第三方库

Gradle代码
‘com.nostra13.universalimageloader:universal-image-loader:1.9.4’

权限

<uses-permission android:name="android.permission.INTERNET" />  
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

ImageLoader加载的类型

"http://site.com/image.png"// from Web  
"file:///mnt/sdcard/image.png" // from SD card
"file:///mnt/sdcard/video.mp4" // from SD card  (video thumbnail)
"content://media/external/images/media/13" // from content provider
"content://media/external/video/media/13" // from content provider (video thumbnail)
"assets://image.png" // from assets
"drawable://" + R.drawable.img // from drawables [用imageView.setImageResource(drawable)来代替]

ImageLoader的加载、显示配置:

加载Image时的配置(ImageLoaderConfiguration)

自定义配置 - 通过new ImageLoaderConfiguration.Builder().builder()方法进行实例化。
默认配置 - 通过ImageLoaderConfiguration 的createDefault进行实例化。

  • 默认配置
File diskCache = StorageUtils.getOwnCacheDirectory(context, "BNJ_IMAGE_CACHE/");  
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context)
		.diskCache(new UnlimitedDiscCache(diskCache)) // 设置缓存路径
		.memoryCacheSize(2 * 1024) // 设置缓存的最大字节
		.diskCacheFileNameGenerator(new Md5FileNameGenerator())  // 加密
		.denyCacheImageMultipleSizesInMemory() // 禁止缓存显示不同大小的同一张图片
		.memoryCacheExtraOptions(800, 760) // 保存每个缓存图片的最大长和宽
		.diskCacheFileCount(100) //缓存的File数量
		.build();

使用
通过ImageLoader的getInstance().init()方法传入上述options对象.

显示Image时的配置(DisplayImageOptions)

自定义配置 - 通过new DisplayImageOptions.Builder().builder()方法实例化对象

DisplayImageOptions options = new DisplayImageOptions.Builder()  
           .showImageOnLoading(R.drawable.ic_stub) // 设置加载时的图片 (使用loadImage方法加载时无效)
           .showImageForEmptyUri(R.drawable.ic_empty) // resource or drawable  
           .showImageOnFail(R.drawable.ic_error) // 设置加载失败的图片
           .cacheInMemory(true) //设置使用内存缓存
           .cacheOnDisk(true)  //使用文件缓存
           .displayer(new RoundedBitmapDisplayer(20))  // 设置成圆角图片    
           .bitmapConfig(Bitmap.Config.RGB_565)  //减少内存消耗
		   .delayBeforeLoading(100) //设置下载图片前的延时
           .imageScaleType(ImageScaleType.EXACTLY_STRETCHED)
   		   .considerExifParams(false) //是否考虑JPEG图像EXIF参数(旋转,翻转)
           .build();  

ImageSize size= new ImageSize(300,300);(大小可以通过创建ImageSize对象设置)

上述图片显示displayer  
//显示圆角 RoundedBitmapDisplayer
//淡入显示 FadeInBitmapDisplayer

加载图片的方法

loadImage跟displayImage

A.ImageLoader.getInstance().loadImage(uri地址,图片大小,上述配置,监听器,进度监听器);
B.ImageLoader.getinstance().displayImage(uri地址,控件,上述配置,监听器,进度监听器);


区别
A方法可以设置图片大小,即自定义下载图片的大小
B方法会根据控件大小及ImageScaleType来裁剪图片
常用displayImage方法


监听器有两种
SimpleImageLoadingListener(简单的监听器)
ImageLoadingListener (该监听器能实现 加载图片取消时,失败时的方法)
ImageLoadingProgressListener
最后在监听器的onLoadingComplete方法里,设置图片显示即可


进阶
listView.setOnScrollListener(new PauseOnScrollListener(imageLoader, pauseOnScroll, pauseOnFling));
第一个参数是imageLoader,第二个参数是滑动时是否加载图片,第三个参数是猛的滑动时是否加载图片

OOM问题

如果使用了ImageLoader出现OutOfMemoryError的话,那么可以通过下列方法解决
关闭memory的cache。

减少线程池的大小
用Bitmap.Config.RGB565代替ARGB8888
使用.imageScaleType(ImageScaleType.EXACTLY 或ImageScaleType.IN_SAMPLE_INT)
使用.diskCacheExtraOption(480, 320, null)

获取缓存文件

1
2
DiskCache diskCache = ImageLoader.getInstance().getDiskCache();
File cacheFile = DiskCacheUtils.findInCache(imgpath, diskCache);

ImageView ScaleType

ImageLoader的使用及封装

使用

1.全局初始化ImageLoader,配置ImageLoader的参数(ImageLoaderConfiguration)
2.配置图片加载的参数(DisplayImageOptions)
3.创建ImageLoader的对象,调用displayImage方法

封装

1.利用单例模式创建ImageLoaderTool的对象

public class ImageLoaderTool{

	private static ImageLoader imageLoader;//用于全局初始化
	private static ImageLoaderConfiguration configuration;//配置ImageLoader的参数

	private static class Holder{ //单例模式
		private static final ImageLoaderTool imageLoaderTool = new ImageLoaderTool();
	}

	public static ImageLoaderTool getInstance(){
		if(configuration==null || imageLoader==null){
			throw new RunTimeException ("Must be call the method InitImageLoader(Context context) in Application");
		}
		return Holder.imageLoaderTool;
	}
}

2.初始化ImageLoaderConfiguration

public static void initImageLoader(Context context) {
    File diskCache = StorageUtils.getOwnCacheDirectory(context, "TJD_NBA/");
    if (configuration == null) {
        configuration = new ImageLoaderConfiguration.Builder(context)
                .diskCache(new UnlimitedDiskCache(diskCache))
                .diskCacheFileNameGenerator(new Md5FileNameGenerator()) //md5加密
                .memoryCacheSize(1024 * 2)//缓存最大字节
                .memoryCache(new LruMemoryCache(5 * 1024 * 1024))//解决缓存listview滑动后显示默认图
                .memoryCacheExtraOptions(800, 760)// 保存每个缓存图片的最大长和宽
                .diskCacheFileCount(100) //缓存的File数量
                .build();
    }
    if (imageLoader == null) {
        imageLoader = ImageLoader.getInstance();
        imageLoader.init(configuration);
    }
}

3.封装DisplayImage方法

/**
 * 加载drawable图片,不能加载系统的drawable 即android:drawable
 *
 * @param resid
 * @param imageView
 */
public void loadImageFromDrawable(int resid, ImageView imageView) {
    imageLoader.displayImage(DRAWABLE_PREFIX + resid, imageView);
}b

示例 - 封装ImageLoader

使用ImageLoader时加载相同URL的问题

//使用displayImage,而不使用loadImage,因为loadImage会导致当同时加载同一个url的时候出现task被取消的情况
//详情见https://github.com/nostra13/Android-Universal-Image-Loader/issues/804

// 解决方法
 ImageSize size = new ImageSize(Functions.getScreenWidthPix(getActivity()), Functions.getScreenHeightPix(getActivity()));
 NonViewAware imageAware = new NonViewAware(size, ViewScaleType.CROP);

解决listvie宽度设置wwrap_content无效的方法

stackoverflow大佬

现象
listview宽度设置wrap_content无效
解决办法,添加FrameLayout跟LinearLayout设置weight

修改前代码

<ListView
android:id="@+id/listView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.3"
android:background="黑色"
android:divider="@null"
android:gravity="center"
android:horizontalSpacing="7dp"
android:numColumns="4"
android:paddingLeft="@dimen/common_layout_margin_15dp"
android:paddingRight="@dimen/common_layout_margin_15dp"></ListView>

修改后代码

<LinearLayout
				android:layout_width="wrap_content"
				android:layout_height="wrap_content"
				android:orientation="horizontal">

	<ListView
			android:id="@+id/listView"
			android:layout_width="0dp"
			android:layout_height="wrap_content"
			android:layout_weight="0.3"
			android:background="黑色"
			android:divider="@null"
			android:gravity="center"
			android:horizontalSpacing="7dp"
			android:numColumns="4"
			android:paddingLeft="@dimen/common_layout_margin_15dp"
			android:paddingRight="@dimen/common_layout_margin_15dp"></ListView>

	<FrameLayout
			android:layout_width="0dp"
			android:layout_height="match_parent"
			android:layout_weight="0.7"
			android:background="蓝色" />

</LinearLayout>


文章作者:TanJunDang

https://tanjundang.github.io/2015/09/17/ImageLoaderTool/