Android图片加载库—Universal-ImageLoader用法详解

这里写图片描述

介绍

Android-Universal-Image-Loader是一个开源的UI组件程序,该项目的目的是提供一个可重复使用的仪器为异步图像加载,缓存和显示。

1、 多线程下载图片,图片可以来源于网络,文件系统,项目文件夹assets中以及drawable中等
2、支持随意的配置ImageLoader,例如线程池,图片下载器,内存缓存策略,硬盘缓存策略,图片显示选项以及其他的一些配置
3、支持图片的内存缓存,文件系统缓存或者SD卡缓存
4、支持图片下载过程的监听
5、根据控件(ImageView)的大小对Bitmap进行裁剪,减少Bitmap占用过多的内存
6、较好的控制图片的加载过程,例如暂停图片加载,重新开始加载图片,一般使用在ListView,GridView中,滑动过程中暂停加载图片,停止滑动的时候去加载图片
7、提供在较慢的网络下对图片进行加载

特点

多线程的图像加载的可能性的宽调谐对ImageLoader的配置(线程池的大小,HTTP选项,内存和光盘高速缓存,显示图像,以及其他)的图像的可能性中的缓存存储器和/或设备的文件器系统(或SD卡)

Widget支持
Android 1.5以上支持
简单描述一下这个项目的结构:每一个图片的加载和显示任务都运行在独立的线程中,除非这个图片缓存在内存中,这种情况下图片会立即显示。如果需要的图片缓存在本地,他们会开启一个独立的线程队列。如果在缓存中没有正确的图片,任务线程会从线程池中获取,因此,快速显示缓存图片时不会有明显的障碍。(别人那边借鉴的这段)
流程图:
这里写图片描述

使用方法

这是 一个开源的Android关于下载显示图片的工具类,在这个下载包里面jar文件,用于我们导入项目使用,具体使用方法在包里面也含有。 image-loader.jar 点击下载

设置权限

由于是使用过程中会图片获取要通过网络,并且有缓存设置,所以这2个权限必须要有。

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

清单文件进行配置

新建一个MyApplication继承Application

public class MyApplication extends Application {  

    @Override  
    public void onCreate() {  
        super.onCreate();  

        //创建默认的ImageLoader配置参数  
     ImageLoaderConfiguration configuration = ImageLoaderConfiguration  .createDefault(this);  

        // imageloader初始化配置。
        ImageLoader.getInstance().init(configuration);  
    }  

}  

配置Android Manifest文件

<manifest>  
    <uses-permission android:name="android.permission.INTERNET" />  
    <!-- Include next permission if you want to allow UIL to cache images on SD card -->  
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />  
    ...  
    <application android:name="MyApplication">  
        ...  
    </application>  
</manifest>  

图片加载之前配置参数:
ImageLoaderConfiguration是图片加载器ImageLoader的配置参数,使用了建造者模式,这里是直接使用了createDefault()方法创建一个默认的ImageLoaderConfiguration,当然我们还可以自己设置ImageLoaderConfiguration,设置如下

ImageLoaderConfiguration config = new ImageLoaderConfiguration  
    .Builder(context)  
    .memoryCacheExtraOptions(480, 800) // max width, max height,即保存的每个缓存文件的最大长宽  
    .discCacheExtraOptions(480, 800, CompressFormat.JPEG, 75, null) // Can slow ImageLoader, use it carefully (Better don't use it)/设置缓存的详细信息,最好不要设置这个  
    .threadPoolSize(3)//线程池内加载的数量  
    .threadPriority(Thread.NORM_PRIORITY - 2)  
    .denyCacheImageMultipleSizesInMemory()  
    .memoryCache(new UsingFreqLimitedMemoryCache(2 * 1024 * 1024)) // You can pass your own memory cache implementation/你可以通过自己的内存缓存实现  
    .memoryCacheSize(2 * 1024 * 1024)    
    .discCacheSize(50 * 1024 * 1024)    
    .discCacheFileNameGenerator(new Md5FileNameGenerator())//将保存的时候的URI名称用MD5 加密  
    .tasksProcessingOrder(QueueProcessingType.LIFO)  
    .discCacheFileCount(100) //缓存的文件数量  
    .discCache(new UnlimitedDiscCache(cacheDir))//自定义缓存路径  
    .defaultDisplayImageOptions(DisplayImageOptions.createSimple())  
    .imageDownloader(new BaseImageDownloader(context, 5 * 1000, 30 * 1000)) // connectTimeout (5 s), readTimeout (30 s)超时时间  
    .writeDebugLogs() // Remove for release app  
    .build();//开始构建  

以上的配置看个人需求进行选择,不是所有都要进行配置。
配置好ImageLoaderConfiguration后,调用以下方法来实现初始化:

ImageLoader.getInstance().init(config);//全局初始化此配置  

注:ImageLoaderConfiguration 配置中的.discCacheFileNameGenerator()方法是将缓存下来的文件以什么方式命名里面可以调用的方法有
1.new Md5FileNameGenerator() //使用MD5对UIL进行加密命名
2.new HashCodeFileNameGenerator()//使用HASHCODE对UIL进行加密命名
使用ImageLoader进行图片加载的时候,先要实例化ImageLoader,调用以下方法进行实例化,在每个布局里面都要实例化后再使用。

图片加载中的参数配置
使用ImageLoader进行图片加载的时候,先要实例化ImageLoader,调用以下方法进行实例化,在每个布局里面都要实例化后再使用。

protected ImageLoader imageLoader = ImageLoader.getInstance();  

之后进行显示的图片的各种格式DisplayImageOptions 的设置:

final ImageView mImageView = (ImageView) findViewById(R.id.image);  
String imageUrl = "https://lh6.googleusercontent.com/-55osAWw3x0Q.jpg";  
 ImageSize mImageSize = new ImageSize(100, 100);  


DisplayImageOptions options = new DisplayImageOptions.Builder()  
.showImageOnLoading(R.drawable.ic_launcher) //设置图片在下载期间显示的图片  
.showImageForEmptyUri(R.drawable.ic_launcher)//设置图片Uri为空或是错误的时候显示的图片  
.showImageOnFail(R.drawable.ic_launcher)  //设置图片加载/解码过程中错误时候显示的图片
.cacheInMemory(true)//设置下载的图片是否缓存在内存中  
.cacheOnDisc(true)//设置下载的图片是否缓存在SD卡中  
.considerExifParams(true)  //是否考虑JPEG图像EXIF参数(旋转,翻转)
.imageScaleType(ImageScaleType.EXACTLY_STRETCHED)//设置图片以如何的编码方式显示  
.bitmapConfig(Bitmap.Config.RGB_565)//设置图片的解码类型//  
.decodingOptions(android.graphics.BitmapFactory.Options decodingOptions)//设置图片的解码配置  
//.delayBeforeLoading(int delayInMillis)//int delayInMillis为你设置的下载前的延迟时间
//设置图片加入缓存前,对bitmap进行设置  
//.preProcessor(BitmapProcessor preProcessor)  
.resetViewBeforeLoading(true)//设置图片在下载前是否重置,复位  
.displayer(new RoundedBitmapDisplayer(20))//是否设置为圆角,弧度为多少  
.displayer(new FadeInBitmapDisplayer(100))//是否图片加载好后渐入的动画时间  
.build();//构建完成  


ImageLoader.getInstance().loadImage(imageUrl, mImageSize, options, new SimpleImageLoadingListener(){  

            @Override  
            public void onLoadingComplete(String imageUri, View view,  
                    Bitmap loadedImage) {  
                super.onLoadingComplete(imageUri, view, loadedImage);  
                mImageView.setImageBitmap(loadedImage);  
            }  

        });  

按照你所需要的配置去设置,如果不需要的就可以不做配置。
但是DisplayImageOptions选项中有些选项对于loadImage()方法是无效的,比如showImageOnLoading, showImageForEmptyUri等,

注:

  以上配置中的:
 1).imageScaleType(ImageScaleType imageScaleType)  是设置 图片的缩放方式
     缩放类型mageScaleType:

              EXACTLY :图像将完全按比例缩小的目标大小

              EXACTLY_STRETCHED:图片会缩放到目标大小完全

              IN_SAMPLE_INT:图像将被二次采样的整数倍

              IN_SAMPLE_POWER_OF_2:图片将降低2倍,直到下一减少步骤,使图像更小的目标大小

              NONE:图片不会调整
  2).displayer(BitmapDisplayer displayer)   是设置 图片的显示方式

      显示方式displayer:

              RoundedBitmapDisplayer(int roundPixels)设置圆角图片

              FakeBitmapDisplayer()这个类什么都没做

              FadeInBitmapDisplayer(int durationMillis)设置图片渐显的时间

         SimpleBitmapDisplayer()正常显示一张图片  

之后按照需求调用

loadimage()加载图片

我们先使用ImageLoader的loadImage()方法来加载网络图片

final ImageView mImageView = (ImageView) findViewById(R.id.image);  
        String imageUrl = "https://lh6.googleusercontent.com/-55osAWw3x0Q/URquUtcFr5I/AAAAAAAAAbs/rWlj1RUKrYI/s1024/A%252520Photographer.jpg";  

        ImageLoader.getInstance().loadImage(imageUrl, 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) {  
                mImageView.setImageBitmap(loadedImage);  
            }  

            @Override  
            public void onLoadingCancelled(String imageUri, View view) {  

            }  
        });  

传入图片的url和ImageLoaderListener, 在回调方法onLoadingComplete()中将loadedImage设置到ImageView上面就行了,如果你觉得传入ImageLoaderListener太复杂了,我们可以使用SimpleImageLoadingListener类,该类提供了ImageLoaderListener接口方法的空实现,使用的是缺省适配器模式

final ImageView mImageView = (ImageView) findViewById(R.id.image);  
        String imageUrl = "https://lh6.googleusercontent.com/-55osAWw3x0Q/URquUtcFr5I/AAAAAAAAAbs/rWlj1RUKrYI/s1024/A%252520Photographer.jpg";  

        ImageLoader.getInstance().loadImage(imageUrl, new SimpleImageLoadingListener(){  

            @Override  
            public void onLoadingComplete(String imageUri, View view,  
                    Bitmap loadedImage) {  
                super.onLoadingComplete(imageUri, view, loadedImage);  
                mImageView.setImageBitmap(loadedImage);  
            }  

        });  

如果我们要指定图片的大小该怎么办呢,这也好办,初始化一个ImageSize对象,指定图片的宽和高,代码如下

final ImageView mImageView = (ImageView) findViewById(R.id.image);  
        String imageUrl = "https://lh6.googleusercontent.com/-55osAWw3x0Q/URquUtcFr5I/AAAAAAAAAbs/rWlj1RUKrYI/s1024/A%252520Photographer.jpg";  

        ImageSize mImageSize = new ImageSize(100, 100);  

        ImageLoader.getInstance().loadImage(imageUrl, mImageSize, new SimpleImageLoadingListener(){  

            @Override  
            public void onLoadingComplete(String imageUri, View view,  
                    Bitmap loadedImage) {  
                super.onLoadingComplete(imageUri, view, loadedImage);  
                mImageView.setImageBitmap(loadedImage);  
            }  

        });  

DisplayImage()加载图片

栗子1:

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);  

从上面的代码中,我们可以看出,使用displayImage()比使用loadImage()方便很多,也不需要添加ImageLoadingListener接口,我们也不需要手动设置ImageView显示Bitmap对象,直接将ImageView作为参数传递到displayImage()中就行了,图片显示的配置选项中,我们添加了一个图片加载中ImageVIew上面显示的图片,以及图片加载出现错误显示的图片,效果如下,刚开始显示ic_stub图片,如果图片加载成功显示图片,加载产生错误显示ic_error
这里写图片描述这里写图片描述
1.纯粹为了加载默认配置的一个图片的方法:
public void displayImage(String uri, ImageView imageView) { }
具体实现:

 // imageUrl代表图片的URL地址,imageView代表承载图片的IMAGEVIEW控件
ImageLoader.getInstance().displayImage(imageUrl, imageView);

2.加载自定义配置的一个图片的方法:
public void displayImage(String uri, ImageView imageView, DisplayImageOptions options) {}
具体实现:

// imageUrl代表图片的URL地址,imageView代表承载图片的IMAGEVIEW控件 , options代表DisplayImageOptions配置文件
ImageLoader.getInstance().displayImage(imageUrl, imageView,options);   

3.图片加载时候带加载情况的监听方法:
ImageLoadingListener 用于监听图片的下载情况。

imageLoader.displayImage(imageUrl, imageView, options, new ImageLoadingListener() {  
    @Override  
    public void onLoadingStarted() {  
       //开始加载的时候执行  
    }  
    @Override  
    public void onLoadingFailed(FailReason failReason) {        
       //加载失败的时候执行  
    }   
    @Override   
    public void onLoadingComplete(Bitmap loadedImage) {  
       //加载成功的时候执行  
    }   
    @Override   
    public void onLoadingCancelled() {  
       //加载取消的时候执行  

    }});  

4.图片加载时候,带监听又带加载进度条的情况 调用:

imageLoader.displayImage(imageUrl, imageView, options, new ImageLoadingListener() {  
    @Override  
    public void onLoadingStarted() {  
       //开始加载的时候执行  
    }  
    @Override  
    public void onLoadingFailed(FailReason failReason) {        
       //加载失败的时候执行  
    }      
    @Override      
    public void onLoadingComplete(Bitmap loadedImage) {  
       //加载成功的时候执行  
    }      
    @Override      
    public void onLoadingCancelled() {  
       //加载取消的时候执行  
    },new ImageLoadingProgressListener() {        
      @Override  
      public void onProgressUpdate(String imageUri, View view, int current,int total) {     
      //在这里更新 ProgressBar的进度信息  
      }  
    });  

加载其他来源的图片

使用Universal-Image-Loader框架不仅可以加载网络图片,还可以加载sd卡中的图片,Content provider等,使用也很简单,只是将图片的url稍加的改变下就行了,下面是加载文件系统的图片
[java] view plain copy 在CODE上查看代码片派生到我的代码片

//显示图片的配置  
        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);  

        imageLoader.displayImage(imageUrl, mImageView, options);  

当然还有来源于Content provider,drawable,assets中,使用的时候也很简单,我们只需要给每个图片来源的地方加上Scheme包裹起来(Content provider除外),然后当做图片的url传递到imageLoader中,Universal-Image-Loader框架会根据不同的Scheme获取到输入流
[java] view plain copy 在CODE上查看代码片派生到我的代码片

//图片来源于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"); 

GirdView,ListView加载图片

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

listView.setOnScrollListener(new PauseOnScrollListener(imageLoader, pauseOnScroll, pauseOnFling));  
gridView.setOnScrollListener(new PauseOnScrollListener(imageLoader, pauseOnScroll, pauseOnFling));  

OutOfMemoryError

虽然这个框架有很好的缓存机制,有效的避免了OOM的产生,一般的情况下产生OOM的概率比较小,但是并不能保证OutOfMemoryError永远不发生,这个框架对于OutOfMemoryError做了简单的catch,保证我们的程序遇到OOM而不被crash掉,但是如果我们使用该框架经常发生OOM,我们应该怎么去改善呢?

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();

ListView加载图片:
ListView加载图片

GridView异步加载图片显示
这里写图片描述

<?xml version="1.0" encoding="utf-8"?>  
<GridView xmlns:android="http://schemas.android.com/apk/res/android"  
    android:id="@+id/gridview"  
    android:layout_width="fill_parent"  
    android:layout_height="fill_parent"  
    android:gravity="center"  
    android:horizontalSpacing="4dip"  
    android:numColumns="3"  
    android:stretchMode="columnWidth"  
    android:verticalSpacing="4dip"  
    android:padding="4dip" />  

ViewPager异步加载图片显示

这里写图片描述

Gallery画廊异步加载图片显示
这里写图片描述

<?xml version="1.0" encoding="utf-8"?>  
<Gallery xmlns:android="http://schemas.android.com/apk/res/android"  
    android:id="@+id/gallery"  
    android:layout_width="fill_parent"  
    android:layout_height="wrap_content"  
    android:layout_gravity="center_vertical"  
    android:spacing="1dip" />  

参考资料:

未来之路 的专栏

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值