Universal-Image-Loader的使用,缓存图片,防止错位,滑动暂停下载

该框架的特点:

  1.可以对缓存的大小进行设置,磁盘缓存的路径已经大小,文件夹名的设置

  2.很方便的控制滑动屏幕的时候,停止图片的下载

1.添加依赖与权限:

compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
<!-- 添加网络权限,如果需要从网络上下载图片 -->
    <uses-permission android:name="android.permission.INTERNET" />
    <!-- 添加写外部存储权限,如果需要往sd卡上写图片的话 -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

2.在Application或者activity中进行配置,来确保在Application初始化的时候,整个App中有一个ImageLoader存在

public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();    很多都是默认的设置,并且在实际使用中不需要全部都进行设置,根据需要设置部分就行了
        ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(this)
                //即保存的每个缓存文件的最大长宽,默认等于你的屏幕尺寸,设备屏幕宽高
                .memoryCacheExtraOptions(480, 800)
                .threadPoolSize(3)//线程池内加载的数量
                .threadPriority(Thread.NORM_PRIORITY - 2)//线程优先级,普通-2
                //设置内存缓存不允许缓存一张图片的多个尺寸,默认允许。
                .denyCacheImageMultipleSizesInMemory()
                .memoryCache(new UsingFreqLimitedMemoryCache(2 * 1024 * 1024)) //你可以通过自己的内存缓存实现
                //memoryCacheSize 为 0,则设置该内存缓存的最大字节数为 App 最大可用内存的 1/8。
                // 创建最大的内存缓存百分比,默认为 13%
                .memoryCacheSizePercentage(13)
                .memoryCacheSize(2 * 1024 * 1024) //内存缓存大小
                .diskCacheSize(50 * 1024 * 1024) //磁盘缓存大小
                // 硬盘缓存文件名生成器,默认为哈希文件名生成器 new HashCodeFileNameGenerator()
                .diskCacheFileNameGenerator(new Md5FileNameGenerator())//将保存的时候的URI名称用MD5 加密
                //集合类型的队列处理任务加载和显示图像,LIFO为后进先出,默认为:FIFO 先进先出
                .tasksProcessingOrder(QueueProcessingType.LIFO)
                .diskCacheFileCount(100) //缓存的文件数量
                .diskCache(new UnlimitedDiskCache(new File(Environment.getExternalStorageDirectory()+"/文件名")))//自定义缓存路径
                .imageDownloader(new BaseImageDownloader(this, 5 * 1000, 30 * 1000)) //网络连接时间 (5 s), readTimeout(30 s)超时时间
                //图片显示的配置项。比如加载前、加载中、加载失败应该显示的占位图片,图片是否需要在磁盘缓存,是否需要在内存缓存等。
                .defaultDisplayImageOptions(DisplayImageOptions.createSimple())
                .writeDebugLogs() // 显示调试的log信息
                .build();//开始构建
        ImageLoader.getInstance().init(config);
    }
}

 具体参数说明:

/**  内存缓存与磁盘缓存的设置:
config.diskCache(new )可以使用的对象如下:
        FileCountLimitedDiscCache(可以设定缓存图片的个数,当超过设定值,删除掉最先加入到硬盘的文件)
        LimitedAgeDiscCache(设定文件存活的最长时间,当超过这个值,就删除该文件)
        TotalSizeLimitedDiscCache(设定缓存bitmap的最大值,当超过这个值,删除最先加入到硬盘的文件)
        UnlimitedDiscCache(这个缓存类没有任何的限制)
config.memoryCache(new UsingFreqLimitedMemoryCache())可以使用的缓存:
    1. 只使用的是强引用缓存
    LruMemoryCache(这个类就是这个开源框架默认的内存缓存类,缓存的是bitmap的强引用,下面我会从源码上面分析这个类)
    2.使用强引用和弱引用相结合的缓存有
    UsingFreqLimitedMemoryCache(如果缓存的图片总量超过限定值,先删除使用频率最小的bitmap)
    LRULimitedMemoryCache(这个也是使用的lru算法,和LruMemoryCache不同的是,他缓存的是bitmap的弱引用)
    FIFOLimitedMemoryCache(先进先出的缓存策略,当超过设定值,先删除最先加入缓存的bitmap)
    LargestLimitedMemoryCache(当超过缓存限定值,先删除最大的bitmap对象)
    LimitedAgeMemoryCache(当 bitmap加入缓存中的时间超过我们设定的值,将其删除)
    3.只使用弱引用缓存
    WeakMemoryCache(这个类缓存bitmap的总大小没有限制,唯一不足的地方就是不稳定,缓存的图片容易被回收掉)
*/

基本的设置,也是推荐的初始化:

public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        ImageLoaderConfiguration.Builder config = new ImageLoaderConfiguration.Builder(this);
        config.threadPriority(Thread.NORM_PRIORITY - 2);//普通优先级-2
        config.denyCacheImageMultipleSizesInMemory();//设置内存缓存不允许缓存一张图片的多个尺寸
        config.diskCacheFileNameGenerator(new Md5FileNameGenerator());//MD5命名文件
        config.diskCacheSize(50 * 1024 * 1024); // 50 M磁盘缓存
        config.tasksProcessingOrder(QueueProcessingType.LIFO);//后进先出
        config.diskCache(new UnlimitedDiskCache(new File(Environment.getExternalStorageDirectory()+"/缓存的文件夹名")));
        if (BuildConfig.DEBUG){
            config.writeDebugLogs();//发布release包时,移除log信息
        }
        ImageLoader.getInstance().init(config.build());
    }
}

3.初始化后就可以使用ImageLoader进行图片的下载了:

 如果没有给ImageLoader.displayImage(xxx)这个方法传递Display Options,那么这个方法将会使用默认的Display Options 

 DisplayImageOptions options = new DisplayImageOptions.Builder()   默认的参数配置
                // 正在加载时显示的占位图
                .showImageOnLoading(R.drawable.ic_stub)
                // URL为空时显示的占位图
                .showImageForEmptyUri(R.drawable.ic_empty)
                // 加载失败时显示的占位图
                .showImageOnFail(R.drawable.ic_error)
                // 在加载前是否重置 view,默认为false
                .resetViewBeforeLoading(false)
                //设置在开始加载前的延迟时间,单位为毫秒,通过 Builder 构建的对象默认为 0
                .delayBeforeLoading(1000)
                // 是否缓存在内存中,通过 Builder 构建的对象默认为 false
                .cacheInMemory(false)
                // 是否缓存在磁盘中,通过 Builder 构建的对象默认为 false。
                .cacheOnDisk(false)
                //缓存在内存之前的处理程序,默认为 null
                .preProcessor(null)
                //缓存在内存之后的处理程序,默认为 null。
                .postProcessor(null)
                //下载器需要的辅助信息。下载时传入ImageDownloader.getStream(String, Object)的对象,方便用户自己扩展,默认为 null。
                .extraForDownloader(null)
                // 是否考虑图片的 EXIF 信息,通过 Builder 构建的对象默认为 false。
                .considerExifParams(false)
                // 图片的缩放类型,通过 Builder 构建的对象默认为IN_SAMPLE_POWER_OF_2
                .imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2)
                // bitmap的质量,默认为ARGB_8888
                .bitmapConfig(Bitmap.Config.ARGB_8888)
                //为 BitmapFactory.Options,用于BitmapFactory.decodeStream(imageStream, null, decodingOptions)得到图片尺寸等信息。
                .decodingOptions(null)
                // 在ImageAware中显示 bitmap 对象的接口。可在实现中对 bitmap 做一些额外处理,比如加圆角、动画效果。
                .displayer(new SimpleBitmapDisplayer())
                // handler 对象,默认为 null
                .handler(new Handler())
                .build();

4.加载网络图片的方式

 //1.火球加载图片的对象,单例
        ImageLoader imageLoader = ImageLoader.getInstance();
        //2.为图片设置参数
        DisplayImageOptions options = new DisplayImageOptions.Builder()
                .showImageOnLoading(R.mipmap.ic_launcher) //设置图片在下载期间显示的图片
                .showImageForEmptyUri(R.mipmap.ic_launcher)//设置图片Uri为空或是错误的时候显示的图片
                .showImageOnFail(R.mipmap.ic_launcher)  //设置图片加载/解码过程中错误时候显示的图片
                .cacheInMemory(true)//设置下载的图片是否缓存在内存中
                .cacheOnDisk(true)//设置下载的图片是否缓存在SD卡中
                .considerExifParams(true)  //是否考虑JPEG图像EXIF参数(旋转,翻转)
                /*
                    EXACTLY :图像将完全按比例缩小的目标大小
                    EXACTLY_STRETCHED:图片会缩放到目标大小完全
                    IN_SAMPLE_INT:图像将被二次采样的整数倍
                    IN_SAMPLE_POWER_OF_2:图片将降低2倍,直到下一减少步骤,使图像更小的目标大小
                    NONE:图片不会调整
                 */
                .imageScaleType(ImageScaleType.EXACTLY_STRETCHED)//设置图片以如何的编码方式显示
                .bitmapConfig(Bitmap.Config.RGB_565)//设置图片的解码类型
                //.delayBeforeLoading(int delayInMillis)//delayInMillis为你设置的下载前的延迟时间
                //设置图片加入缓存前,对bitmap进行设置
                //.preProcessor(BitmapProcessor preProcessor)
                .resetViewBeforeLoading(true)//设置图片在下载前是否重置,复位
                /*
                 显示方式displayer:效果不能重叠
                    RoundedBitmapDisplayer(int roundPixels)设置图片四个角的弧度,
            new CircleBitmapDisplayer() 就能显示圆形图 FakeBitmapDisplayer()这个类什么都没做 FadeInBitmapDisplayer(int durationMillis)设置图片渐显的时间         SimpleBitmapDisplayer()正常显示一张图片 
*/ .displayer(new RoundedBitmapDisplayer(20))//是否设置为圆角,弧度为多少 .displayer(new FadeInBitmapDisplayer(100))//是否图片加载好后渐入的动画时间 .build();//构建完成 //3.加载默认配置的一个图片 ImageLoader.getInstance().displayImage(imageUrl, imageView) // 加载自定义配置的一个图片的 ImageLoader.getInstance().displayImage(imageUrl, imageView,options);//options代表上面设置的参数 //图片加载时候带加载情况的监听 imageLoader.displayImage(imageUrl, 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) { //加载取消的时候执行 } }); //图片加载时候,带监听又带加载进度条的情况 imageLoader.displayImage(imageUrl, 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) { //加载成功的时候执行,view为imageView,在这里判断tag防止错位 } @Override public void onLoadingCancelled(String imageUri, View view) { //加载取消的时候执行 } }, new ImageLoadingProgressListener() { @Override public void onProgressUpdate(String imageUri, View view, int current, int total) { //在这里更新 ProgressBar的进度信息,当前进度与总进度 , 如果是从缓存中获取的图片就不会执行该方法 } });

明确指定的访问本地图片:

 String imageUri = "http://site.com/image.png"; //从网络获取
 String imageUri = "file:///mnt/sdcard/image.png"; // 从SD card
 String imageUri = "content://media/external/audio/albumart/13"; //内容提供者
 String imageUri = "assets://image.png"; // 访问工程中assets文件夹中的
 String imageUri = "drawable://" + R.drawable.image; //访问drawables (only images, non-9patch)

GirdView,ListView加载图片, 滑动屏幕的时候停止下载图片

相信大部分人都是使用GridView,ListView来显示大量的图片,而当我们快速滑动GridView,ListView,我们希望能停止图片的加载,而在GridView,ListView停止滑动的时候加载当前界面的图片,这个框架当然也提供这个功能,使用起来也很简单,它提供了PauseOnScrollListener这个类来控制ListView,GridView滑动过程中停止去加载图片,该类使用的是代理模式

/**
         * 第一个参数就是我们的图片加载对象ImageLoader, 
         * 第二个是控制是否在滑动过程中暂停加载图片,如果需要暂停传true就行了
         * 第三个参数是控制猛的滑动界面的时候图片是否加载
         */
        listView.setOnScrollListener(new PauseOnScrollListener(imageLoader, pauseOnScroll, pauseOnFling));

5.清除缓存

ImageLoader.getInstance().clearMemoryCache();  // 清除内存缓存
ImageLoader.getInstance().clearDiskCache();  // 清除本地缓存

注意事项:
  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();

posted @ 2016-10-05 13:41  ts-android  阅读(717)  评论(0编辑  收藏  举报