AndroidUniversalImageLoader图片异步加载类库的使用

Stella981
• 阅读 407
  • 开发App过程中,免不了要进行网络请求操作进行数据交换,比如下载图片,如果自己写一个下载图片的类进行操作的话,要考虑太多太多内容,必须线程池,内存溢出,图片磁盘缓存操作,图片内存缓存操作等等,相当麻烦。好在伟大的开源者们已经写好了一个比较完美的开源类库供大家使用Android-Universal-Image-Loader,这个类库已经被许多知名的软件所采用,当时我自己用这个开源类库的时候,百度了一大推,有查看了官方文档。现在把记录写下来供大家参考。

    一、介绍:

    Android-Universal-Image-Loader的目的是提供一个功能强大的,灵活的,高度可定制的图像加载,缓存和显示工具。它提供了大量的配置选项,并很好地控制图像加载和缓存。

    类库的特点

    l 多线程的图像加载(同步或异步)

    l 灵活的图像加载配置选项(线程执行,下载,解码,内存和磁盘缓存,图像显示选项)

    l 自定义每个显示图像的配置

    l 在内存或磁盘上缓存(设备内存或SD卡)

    l 监听加载进程(包括下载进度)

    效果图

    AndroidUniversalImageLoader图片异步加载类库的使用

    二、用法

    先来看下引入该类包后,加载图片的运行流程图

    AndroidUniversalImageLoader图片异步加载类库的使用

    从图中可看出,加载图片的时候一共分为三种情况:

    (post process Bitmap一步,实际就是对该图片进行处理,比如加水印,加圆角等等,该框架没有给出具体实现,默认为null,如有需要自己可以实现,所以分析的时候可以忽略)

    1. 图片在内存中缓存:直接显示图片。

    2. 图片在磁盘中缓存:先解码,再暂时缓存到内存中,最后显示。

    3. 图片没有缓存:先下载,再是否缓存到磁盘和内存,最后显示。

    (一) Include Library

    官网下载依赖jar包,导入工程中libs文件夹下并添加到工程路径即可。

    (二) 加权限

    ...

    (三)全局配置

    全局配置我一般写个类继承application,然后在Mainfest文件中声明

    public class MyApplication extends Application {

    @Override
    public void onCreate() {
        // TODO Auto-generated method stub
        super.onCreate();
        initImageLoader(getApplicationContext());
    }
    public static void initImageLoader(Context context){
        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(); // Initialize ImageLoader with configuration.初始化配置 ImageLoader.getInstance().init(config); } }

    以上的配置大部分都有默认值,按照自己的需要进行配置,没必要全部都写上,现在的显示配置也是一样。

    (四)显示配置

    显示配置是具体到每个显示图片任务的配置

    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(); (五)配置完了使用

    用默认配置显示:ImageLoader.getInstance().displayImage(imageUrl, imageView);

    用自定义配置显示:ImageLoader.getInstance().displayImage(imageUrl, imageView,options);

    带监听事件的显示:

    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() {
    //加载取消的时候执行
    }}); 带监听事件和进度条的显示:

    imageLoader.displayImage(imageUri, 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) { ... } }, new ImageLoadingProgressListener() { @Override public void onProgressUpdate(String imageUri, View view, int current, int total) { ... } });

    有的文章提出加载本地图片也用ImageLoader.getInstance().displayImage,完全没有必要。

    三、注意事项

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

    对该类库源码的解析可以参考这篇大神的文章http://blog.csdn.net/xiaanming/article/details/39057201

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
浩浩 浩浩
3年前
【Flutter实战】图片和Icon
3.5图片及ICON3.5.1图片Flutter中,我们可以通过Image组件来加载并显示图片,Image的数据源可以是asset、文件、内存以及网络。ImageProviderImageProvider是一个抽象类,主要定义了图片数据获取的接口load(),从不同的数据源获取图片需要实现不同的ImageProvi
Souleigh ✨ Souleigh ✨
3年前
前端性能优化 - 雅虎军规
无论是在工作中,还是在面试中,web前端性能的优化都是很重要的,那么我们进行优化需要从哪些方面入手呢?可以遵循雅虎的前端优化35条军规,这样对于优化有一个比较清晰的方向.35条军规1.尽量减少HTTP请求个数——须权衡2.使用CDN(内容分发网络)3.为文件头指定Expires或CacheControl,使内容具有缓存性。4.避免空的
Stella981 Stella981
3年前
Python3:sqlalchemy对mysql数据库操作,非sql语句
Python3:sqlalchemy对mysql数据库操作,非sql语句python3authorlizmdatetime2018020110:00:00coding:utf8'''
Stella981 Stella981
3年前
Android So动态加载 优雅实现与原理分析
背景:漫品Android客户端集成适配转换功能(基于目标识别(So库35M)和人脸识别库(5M)),导致apk体积50M左右,为优化客户端体验,决定实现So文件动态加载.!(https://oscimg.oschina.net/oscnet/00d1ff90e4b34869664fef59e3ec3fdd20b.png)点击上方“蓝字”关注我
Wesley13 Wesley13
3年前
35岁是技术人的天花板吗?
35岁是技术人的天花板吗?我非常不认同“35岁现象”,人类没有那么脆弱,人类的智力不会说是35岁之后就停止发展,更不是说35岁之后就没有机会了。马云35岁还在教书,任正非35岁还在工厂上班。为什么技术人员到35岁就应该退役了呢?所以35岁根本就不是一个问题,我今年已经37岁了,我发现我才刚刚找到自己的节奏,刚刚上路。
Wesley13 Wesley13
3年前
IOS 图片加载过多导致内存警报的释放内存操作
IOS加载图片越来越多会导致内存警报,此时应该暂停下载操作清除缓存。 (void)applicationDidReceiveMemoryWarning:(UIApplication )application{    //停止下载所有的图片    SDWebImageManager sharedManager
Stella981 Stella981
3年前
SDWebImage 实现原理及大致介绍
一、SDWebImage实现原理:1.首先让占位图先显示。2.SDWebImageManage交给SDImageCache先从内存中查找是否有图片,会以URL作为数据的索引在内存中查找是否有对应的缓存。3.如果有缓存,通过代理进行回调展示图片。4.如果内存缓存中没有找到,生成NSInvocati