Android 使用imageLoader来加载显示图片
简介
Android上最让人头疼的莫过于从网络获取图片、显示、回收,任何一个环节有问题都可能直接OOM,这个项目或许能帮到你。Universal Image Loader for Android的目的是为了实现异步的网络图片加载、缓存及显示,支持多线程异步加载。它最初来源于Fedor Vlasov的项目,且自此之后,经过大规模的重构和改进
imageloader 加载图片的一般流程是先判断内存中是否有对应的Bitmap,再判断磁盘(disk)中是否有,如果没有就从网络中加载。最后根据原先在UIL中的配置判断是否需要缓存Bitmap到内存或磁盘中。Bitmap加载完后,就对它进行解析,然后显示到特定的ImageView中,
加载过程分析简图:
使用imageLoader可以实现
- 多线程下载图片,图片可以来源于网络,文件系统,项目文件夹assets中以及drawable中等
- 支持随意的配置ImageLoader,例如线程池,图片下载器,内存缓存策略,硬盘缓存策略,图片显示选项以及其他的一些配置
- 支持图片的内存缓存,文件系统缓存或者SD卡缓存
- 支持图片下载过程的监听
- 根据控件(ImageView)的大小对Bitmap进行裁剪,减少Bitmap占用过多的内存
- 较好的控制图片的加载过程,例如暂停图片加载,重新开始加载图片,一般使用在ListView,GridView中,滑动过程中暂停加载图片,停止滑动的时候去加载图片
- 提供在较慢的网络下对图片进行加载
初始化imageloader
方式一:
//创建默认的ImageLoader配置参数
ImageLoaderConfiguration configuration = ImageLoaderConfiguration .createDefault(this);
//Initialize ImageLoader with configuration.
ImageLoader.getInstance().init(configuration);
方式二:
File cacheDir =getExternalStoragePath()+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))//自定义缓存路径 ,这里是缓存到sd卡上 .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);
// 获取SD卡路径public String getExternalStoragePath() {// 获取SdCard状态String state = android.os.Environment.getExternalStorageState();// 判断SdCard是否存在并且是可用的if (android.os.Environment.MEDIA_MOUNTED.equals(state)) {if (android.os.Environment.getExternalStorageDirectory().canWrite()) {return android.os.Environment.getExternalStorageDirectory().getPath();}}return null;}
方式三:
// 获取最大内存int maxMemorySize = (int) (Runtime.getRuntime().maxMemory());ImageLoaderConfiguration.Builder config = new ImageLoaderConfiguration.Builder(context);config.threadPriority(Thread.NORM_PRIORITY - 2);config.denyCacheImageMultipleSizesInMemory();// 不会在内存中缓存多个大小的图片config.diskCacheFileNameGenerator(new Md5FileNameGenerator());// 为了保证图片名称唯一config.diskCacheSize(maxMemorySize / 10);// 内存缓存大小默认是:app可用内存的1/8,这里设为1/10config.tasksProcessingOrder(QueueProcessingType.LIFO);config.writeDebugLogs(); // Remove for release app// Initialize ImageLoader with configuration.ImageLoader.getInstance().init(config.build());
最好是使用用方式三,这里是动态获取内存的大小 ,可以有效的避免一些内存溢出的效果 。。。。
当然要将图片缓存到本地自定义的路径中,可以使用用方式二与方式三相结合使用
特别说明:
1、ImageLoaderConfiguration 配置中的.discCacheFileNameGenerator()方法是将缓存下来的文件以什么方式命名
里面可以调用的方法有 1.new Md5FileNameGenerator() //使用MD5对UIL进行加密命名
2.new HashCodeFileNameGenerator()//使用HASHCODE对UIL进行加密命名
使用中的图像操作
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 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();//构建完成
特别说明:
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()正常显示一张图片
加载中使用的地址
String imageUri = "http://site.com/image.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文件
"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 (non-9patch images)
设置显示图片
displayImage方法
可以根据需要使用不同的构造
1、ImageLoader.getInstance().displayImage(uri, imageView);
2、 ImageLoader.getInstance().displayImage(uri, imageView, options);
3、 ImageLoader.getInstance().displayImage(uri, imageView, listener);
4、 ImageLoader.getInstance().displayImage(uri, imageView, options, listener);
5、 ImageLoader.getInstance().displayImage(uri, imageView, options, listener, progressListener);
imageUrl 图片的URL地址imageView 显示图片的ImageView控件 options DisplayImageOptions配置信息 listener 图片下载情况的监听progressListener 图片下载进度的监听
loadImage方法
并常用的加载方法:
ImageView mImageView = (ImageView) findViewById(R.id.image); String imageUrl = ""; ImageLoader.getInstance().loadImage(imageUrl, new SimpleImageLoadingListener(){ @Override public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) { super.onLoadingComplete(imageUri, view, loadedImage); mImageView.setImageBitmap(loadedImage); } });
初始化一个图片显示大小
ImageView mImageView = (ImageView) findViewById(R.id.image); String imageUrl = ""; 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); } });
设置options参数加载
ImageView mImageView = (ImageView) findViewById(R.id.image); String imageUrl = ""; ImageSize mImageSize = new ImageSize(100, 100); //设置图片显示大小 为100 X 100//显示图片的配置 DisplayImageOptions options = new DisplayImageOptions.Builder() .cacheInMemory(true) .cacheOnDisk(true) .bitmapConfig(Bitmap.Config.RGB_565) .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); } });
加载图片的监听
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() { //加载取消的时候执行 }});
特别说明
在图片加载成功之后(onlaodingComplete()方法中),可以对获取到的Bitmap进行各种大小设置,图形裁剪操作以及动画效果添加等,最后再加图片展示到控件上
/** * 图片加载第一次显示监听器 * @author Administrator * */ 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); } } } @Override public void onLoadingStarted(String imageUri, View view) { spinner.setVisibility(View.VISIBLE); } @Override public void onLoadingFailed(String imageUri, View view, FailReason failReason) { String message = null; switch (failReason.getType()) { // 获取图片失败类型 case IO_ERROR: // 文件I/O错误 message = "Input/Output error"; break; case DECODING_ERROR: // 解码错误 message = "Image can't be decoded"; break; case NETWORK_DENIED: // 网络延迟 message = "Downloads are denied"; break; case OUT_OF_MEMORY: // 内存不足 message = "Out Of Memory error"; break; case UNKNOWN: // 原因不明 message = "Unknown error"; break; } Toast.makeText(ImagePagerActivity.this, message, Toast.LENGTH_SHORT).show(); } }
}
设置进度的方法
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的进度信息 } });
缓存的清理
@Override
public void onDestroy() { super.onDestroy(); imageLoader.clearMemoryCache(); imageLoader.clearDiskCache();
}
// 获取占用最大内存maxMemory = (int) Runtime.getRuntime().maxMemory();
if (maxMemory < 40 * 1024 * 1024) {ImageLoader.getInstance().clearMemoryCache();ImageLoader.getInstance().clearDiskCache();}
这里可以依据需求来设定,我这里采用的是检测 下内存,如果内存大小小于40M,那么在销毁的时候 ,清理缓存 ,这样处理可以有效的解决下加载图片过程中出现的内存溢出问题(例如 512M内存的手机)
在ListView与GridView中滑动过程中停止加载图片
listView.setOnScrollListener(new PauseOnScrollListener(imageLoader, pauseOnScroll, pauseOnFling));
gridView.setOnScrollListener(new PauseOnScrollListener(imageLoader, pauseOnScroll, pauseOnFling));
第一个参数就是我们的图片加载对象ImageLoader, 第二个是控制是否在滑动过程中暂停加载图片,如果需要暂停传true就行了,第三个参数控制猛的滑动界面的时候图片是否加载
补充说明
如果经常出现OOM(别人那边看到的,觉得很有提的必要)
①减少配置之中线程池的大小,(.threadPoolSize).推荐1-5;
②使用.bitmapConfig(Bitmap.config.RGB_565)代替ARGB_8888;
③使用.imageScaleType(ImageScaleType.IN_SAMPLE_INT)或者.imageScaleType(ImageScaleType.EXACTLY);
④避免使用RoundedBitmapDisplayer.他会创建新的ARGB_8888格式的Bitmap对象;
⑤使用.memoryCache(new WeakMemoryCache()),不要使用.cacheInMemory();
Android自定义控件ImageViwe(一)——依据控件的大小来设置缩放图片显示
点击打开链接
Android自定义ImageView(二)——实现双击放大与缩小图片
点击打开链接
Android自定义控件ImageViwe(三)——随手指进行图片的缩放
点击打开链接
Android自定义控件ImageViwe(四)——多点触控实现图片的自由移动
点击打开链接
Android ListView分组排序显示数据
点击打开链接
Android自定义下拉刷新功能的ListView
点击打开链接
Android音乐播放器高级开发
点击打开链接
Android自定义控件之流式布局
点击打开链接
Android 使用imageLoader来加载显示图片相关推荐
- thinkphp+ajax无刷新分页并加载显示图片
2019独角兽企业重金招聘Python工程师标准>>> 最近自己用thinkphp和bootstrap做一个小站点,在用到ajax与后台数据库交互实现无刷新分页时,因为我需要返回的数 ...
- Axure教程:中继器如何加载显示图片
编辑导语:在原型设计中,很多场景会应用到"中继器"这个元件.那么中继器如何加载显示图片的操作?很多新手都会无从下手.本文作者详细讲解了中继器加载显示图片的方法,供你学习. 一.元件 ...
- android主动显示流程,Activity加载显示基本流程
本文章是基于Android源码6.0讲解Activity加载显示基本流程 首先上一张图给大家一个直观的了解 首先一个布局页面的加载是在Activity中的setContentView(R.layout ...
- android圆角glide,Glide加载圆角图片的方法
原标题:Glide加载圆角图片的方法 现在在市面上很多App的UI设计都会出现圆角图片的显示.Glide本身也提供了圆角图片的加载方式.但是我们在开发中有可能遇到只要顶部展示圆角,或者某一个角是圆角. ...
- Android使用ImageLoader异步加载网络图片(一)读取单张图片
这里我写的是读取单张的图片从网络读取,和listview多张图片的读取首先是单张的读取这篇博客只写了读取单张的读取多张的下一篇写 此例子的代码 已上传资源页 由于昨天时间比较紧所以,这个Demo 的源 ...
- android动态图片适配,Android适配利用webview加载后图片显示过大的问题解决
前言 最近在开发过程中,需要用webview控件来展示文章的详情页面,流程是通过请求后台数据,然后用控件加载,而后台返回的文章详情页面是直接网页端使用的,并没有对移动端进行适配,导致webview加载 ...
- android 排行榜中异步加载头像图片
排行榜用的是RecyclerView显示,适配器使用BaseQuickAdapter,效果如下 1.RecycylerView适配器的使用 先引入依赖,然后新建类RegionList2Adapter继 ...
- 预加载显示图片的艺术
一般情况下网页中的图片都是随文档流依次加载的,什么时候用到则什么时候加载,但是有些时候这样的加载方式往往会影响用户体验,比如鼠标hover变换背景图片的时候,只有鼠标移入才会对变换的图片进行加载,这样 ...
- mfc cimage加载显示图片_在微信小程序里实现图片预加载组件
网页中的图片预加载 我们知道在 Web 页面中实现图片的预加载其实很简单,通常的做法是在 JS 中使用 Image 对象即可,代码大致如下 var image = new Image() image. ...
最新文章
- Maven项目加载JAR包
- 调用父级方法_通信:找到任意组件实例的findComponents系列方法,5个终极方案
- hadoop基本命令
- 二层交换机、三层交换机和路由器的基本工作原理区别—Vecloud
- 支付开发填坑记之支付宝
- 用数学诠释生命——当今生物信息与计算生物学回顾(一)
- no signatures that match those in shared user android.uid.system; ignoring!
- 搭建hbase-0.94.26集群环境
- 15年来这8门编程语言位置十分稳定,C#从低谷开始爬升
- 软件故障_一些主要的软件故障
- window下版本控制工具Git 客户端安装
- python飞机大战创建多个敌机_Python 项目飞机大战- 03 游戏背景和敌机出场
- DjangoForm组件初识
- sql modify 会丢失数据么_为什么U盘的数据会丢失?找对方法,轻松应对
- linux下的僵尸进程 - Zombie
- 修改鼠标手形 闪烁 在填写文字内容后也一直在闪烁
- c语言098十进制输出,C语言题库098.doc
- matlab 仿真短路故障设置,基于MATLAB的电力系统故障分析及仿真
- 程序员的数学【最优化】
- Mac苹果电脑登录其他用户教程
热门文章
- 【OpenCV】OpenCV函数精讲之 -- 命名空间
- 端到端半监督目标检测框架Instant-Teaching:
- 人工智能相关领域的国际顶会介绍
- 《Python编程从入门到实践》记录之第6章 字典操作知识总结——字典遍历、字典嵌套等(思维导图)
- HALCON学习之旅(七)
- 卷王李富贵算法每日一题--分治算法(三)--逃亡
- 推荐系统遇上深度学习(二)--FFM模型理论和实践
- 无法从外部连接MySQL_无法从外部VPC连接到RDS实例(ERROR 2003(HY000)无法连接到MySQL服务器)...
- c#日期转换周几_RPA经验:使用 selector 选择日期
- 会议管理的十条黄金原则