文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Android Universal ImageLoader 缓存图片

2022-06-06 09:13

关注

项目介绍:

Android上最让人头疼的莫过于从网络获取图片、显示、回收,任何一个环节有问题都可能直接OOM,这个项目或许能帮到你。Universal Image Loader for Android的目的是为了实现异步的网络图片加载、缓存及显示,支持多线程异步加载。它最初来源于Fedor Vlasov的项目,且自此之后,经过大规模的重构和改进。

特性列举:

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

使用过程:

创建默认的ImageLoader,所有的操作都由ImageLoader控制。该类使用单例设计模式,所以如果要获取该类的实力,需要调用getInstance()方法。在使用ImageLoader显示图片之前,你首先要初始化它的配置,调用ImageLoaderConfiguration的init()方法,然后你就可以实现各种的显示了。


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

自定义配置imageloader, 就像你已经知道的,首先,你需要使用ImageLoaderConfiguration对象来初始化ImageLoader。由于ImageLoader是单例,所以在程序开始的时候只需要初始化一次就好了。建议你在Activity的onCreate()方法中初始化。如果一个ImageLoader已经初始化过,再次初始化不会有任何效果。下面我们通过ImageLoaderConfiguration.Builder创建一个设置


File cacheDir =StorageUtils.getOwnCacheDirectory(this, "imageloader/Cache"); 
ImageLoaderConfigurationconfig = new ImageLoaderConfiguration 
.Builder(this) 
.memoryCacheExtraOptions(480, 800) // maxwidth, max height,即保存的每个缓存文件的最大长宽 
.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(newMd5FileNameGenerator())//将保存的时候的URI名称用MD5 加密 
.tasksProcessingOrder(QueueProcessingType.LIFO) 
.discCacheFileCount(100) //缓存的文件数量 
.discCache(new UnlimitedDiscCache(cacheDir))//自定义缓存路径 
.defaultDisplayImageOptions(DisplayImageOptions.createSimple()) 
.imageDownloader(new BaseImageDownloader(this,5 * 1000, 30 * 1000)) // connectTimeout (5 s), readTimeout (30 s)超时时间 
.writeDebugLogs() // Remove for releaseapp 
.build();//开始构建 
ImageLoader.getInstance().init(config); 

得到imageLoader


ImageLoader imageLoader imageLoader = ImageLoader.getInstance(); 

使用过程:

(1)图像操作是否参与缓存以及图像效果的配置操作


DisplayImageOptions options = new DisplayImageOptions.Builder() 
.showImageOnLoading(R.drawable.ic_stub) //加载图片时的图片 
.showImageForEmptyUri(R.drawable.ic_empty) //没有图片资源时的默认图片 
.showImageOnFail(R.drawable.ic_error) //加载失败时的图片 
.cacheInMemory(true) //启用内存缓存 
.cacheOnDisk(true) //启用外存缓存 
.considerExifParams(true) //启用EXIF和JPEG图像格式 
.displayer(new RoundedBitmapDisplayer(20)) //设置显示风格这里是圆角矩形 
.build(); 

DisplayImageOptions以下是所有默认配置参数根据需求可以自定义配置


private int imageResOnLoading = 0; 
private int imageResForEmptyUri = 0; 
private int imageResOnFail = 0; 
private Drawable imageOnLoading = null; 
private Drawable imageForEmptyUri = null; 
private Drawable imageOnFail = null; 
private boolean resetViewBeforeLoading = false; 
private boolean cacheInMemory = false; 
private boolean cacheOnDisk = false; 
private ImageScaleType imageScaleType = ImageScaleType.IN_SAMPLE_POWER_OF_2; 
private Options decodingOptions = new Options(); 
private int delayBeforeLoading = 0; 
private boolean considerExifParams = false; 
private Object extraForDownloader = null; 
private BitmapProcessor preProcessor = null; 
private BitmapProcessor postProcessor = null; 
private BitmapDisplayer displayer = DefaultConfigurationFactory.createBitmapDisplayer(); 
private Handler handler = null; 
private boolean isSyncLoading = false; 

(2)图片加载监听器在这里吧可以设置加载时的动画或者进度条之类的东西这里


ImageLoadingListener animateFirstListener = new AnimateFirstDisplayListener(); 
private static class AnimateFirstDisplayListener extends SimpleImageLoadingListener { 
static final List<String> displayedImages = Collections.synchronizedList(new LinkedList<String>()); 
@Override 
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) { 
if (loadedImage != null) { 
ImageView imageView = (ImageView) view; 
boolean firstDisplay = !displayedImages.contains(imageUri); 
if (firstDisplay) { 
FadeInBitmapDisplayer.animate(imageView, 500); 
displayedImages.add(imageUri); 
} 
} 
} 
}

(3)简单设置就可以给ImageView添加图片了


imageLoader.displayImage(imageUrl, imageview, options, animateFirstListener); 

对于本地的图片 ,在其绝对地址前面要加入"file://"。网络图片就直接写路径了。

由于我的这个是最新的包,可能跟以前老的版本不同,看到有些网友说的是:


String imageUri = "/file/upload/202206/06/2al4zxehpd2.png"; // 网络图片 
String imageUri = "file:///mnt/sdcard/image.png"; //SD卡图片 
String imageUri = "content://media/external/audio/albumart/13"; // 媒体文件夹 
String imageUri = "assets://image.png"; // assets 
String imageUri = "drawable://" + R.drawable.image; // drawable文件 

缓存的清理:

缓存的清理可以按需求来定,可以再每个Activity的生命周期函数onDestroy中清理也可以单独设置让用户自行清理。


@Override 
public void onDestroy() { 
super.onDestroy(); 
imageLoader.clearMemoryCache(); 
imageLoader.clearDiskCache(); 
}

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

第一个参数就是我们的图片加载对象ImageLoader, 第二个是控制是否在滑动过程中暂停加载图片,如果需要暂停传true就行了,第三个参数控制猛的滑动界面的时候图片是否加载

OutOfMemoryError:

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

减少线程池中线程的个数,在ImageLoaderConfiguration中的(.threadPoolSize)中配置,推荐配置1-5

在DisplayImageOptions选项中配置bitmapConfig为Bitmap.Config.RGB_565,因为默认是ARGB_8888, 使用RGB_565会比使用ARGB_8888少消耗2倍的内存

在ImageLoaderConfiguration中配置图片的内存缓存为memoryCache(newWeakMemoryCache()) 或者不使用内存缓存

在DisplayImageOptions选项中设置.imageScaleType(ImageScaleType.IN_SAMPLE_INT)或者imageScaleType(ImageScaleType.EXACTLY)

通过上面这些,相信大家对Universal-Image-Loader框架的使用已经非常的了解了,我们在使用该框架的时候尽量的使用displayImage()方法去加载图片,loadImage()是将图片对象回调到ImageLoadingListener接口的onLoadingComplete()方法中,需要我们手动去设置到ImageView上面,displayImage()方法中,对ImageView对象使用的是Weak references,方便垃圾回收器回收ImageView对象,如果我们要加载固定大小的图片的时候,使用loadImage()方法需要传递一个ImageSize对象,而displayImage()方法会根据ImageView对象的测量值,或者android:layout_width and android:layout_height设定的值,或者android:maxWidth and/or android:maxHeight设定的值来裁剪图片

您可能感兴趣的文章:Android ListView实现ImageLoader图片加载的方法Android Imageloader的配置的实现代码Android ImageLoader第三方框架解析Android开发之ImageLoader本地缓存Android开发之ImageLoader使用详解Android图片加载的缓存类非常实用的Android图片工具类Android开发之多媒体文件获取工具类实例【音频,视频,图片等】Android开发之超强图片工具类BitmapUtil完整实例Android开发之图片压缩工具类完整实例Android编程图片加载类ImageLoader定义与用法实例分析


阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-移动开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯