Android进阶笔记15:ListView篇之图片优化
1、图片异步加载:
(1)处理图片的方式:
如果ListView中自定义的Item中有涉及到大量图片的,一定要对图片进行细心的处理,因为图片占的内存是 ListView 项中最头疼的,处理图片的方法大致有以下几种:
①、不要直接拿路径就去循环 BitmapFactory.decodeFile;使用 Options 保存图片大小、不要加载图片到内存去。
②、对图片一定要经过边界压缩尤其是比较大的图片,如果你的图片是后台服务器处理好的那就不需要了。
③、在 ListView 中取图片时也不要直接拿个路径去取图片,而是以 WeakReference(使用 WeakReference 代替强引用。比如可以使用 WeakReference mContextRef)、SoftReference、 WeakHashMap 等的来存储图片信息。
④、在 getView 中做图片转换时,产生的中间变量一定及时释放。
(2)异步加载图片基本思想:
1)、 先从内存缓存中获取图片显示(内存缓冲)
2)、获取不到的话从 SD 卡里获取(SD 卡缓冲)
3)、都获取不到的话从网络下载图片并保存到SD卡同时加入内存并显示(视情况看是否要显示)
原理:
优化一:先从内存中加载,没有则开启线程从 SD 卡或网络中获取,这里注意从 SD 卡获取图片 是放在子线程里执行的,否则快速滑屏的话会不够流畅。
优化二:于此同时,在 adapter 里有个 busy 变量,表示 listview 是否处于滑动状态,如果是滑动状态则仅从内存中获取图片,没有的话无需再开启线程去外存或网络获取图片。
优化三:ImageLoader 里的线程使用了线程池,从而避免了过多线程频繁创建和销毁,如果每次总是 new 一个线程去执行这是非常不可取的,好一点的用的 AsyncTask 类,其实内部也是用到了线程池。在从网络获取图片时,先是将其保存到 sd 卡,然后再加载到内存,这么做的好处是在加载到内存时可以做个压缩处理,以减少图片所占内存。
2. ListView图片错位的原因 和 图片错位的解决方法:
(1)ListView图片错位的原因:
Listview 异步加载图片之所以错位的根本原因是重用了 convertView 且有异步操作。如果不重用 convertView 不会出现错位现象,重用 convertView 但没有异步操作也不会有问题。
我简单分析一下:
当重用 convertView 时,最初一屏显示 7 条记录, getView 被调用 7 次,创建了 7 个 convertView。当 Item1 划出屏幕, Item8 进入屏幕时,这时没有为 Item8 创建新的 view 实例, Item8 复用的是Item1 的 view 如果没有异步不会有任何问题,虽然 Item8 和 Item1 指向的是同一个 view,但滑到Item8 时刷上了 Item8 的数据,这时 Item1 的数据和 Item8 是一样的,因为它们指向的是同一块内存,但 Item1 已滚出了屏幕你看不见。当 Item1 再次可见时这块 view 又涮上了 Item1 的数据。
但当有异步下载时就有问题了,假设 Item1 的图片下载的比较慢,Item8 的图片下载的比较快,你滚上去使 Item8 可见,这时 Item8 先显示它自己下载的图片没错,但等到 Item1 的图片也下载完时你发现Item8 的图片也变成了 Item1 的图片,因为它们复用的是同一个 view。 假设 Item1 的图片下载的比Item8 的图片快,Item1 先刷上自己下载的图片,这时你滑下去,Item8 的图片还没下载完, Item8会先显示 Item1 的图片,因为它们是同一块内存,当 Item8 自己的图片下载完后 Item8 的图片又刷成了自己的,你再滑上去使 Item1 可见, Item1 的图片也会和 Item8 的图片是一样的,因为它们指向的是同一块内存。
(2)图片错位的解决方法:
// 给 ImageView 设置一个 tag
holder.img.setTag(imgUrl);
// 预设一个图片
holder.img.setImageResource(R.drawable.ic_launcher); // 通过 tag 来防止图片错位
if (imageView.getTag() != null && imageView.getTag().equals(imageUrl)) {
imageView.setImageBitmap(result);
}
Android进阶笔记15:ListView篇之图片优化的更多相关文章
- Android进阶笔记12:ListView篇之图片优化
1.图片异步加载: (1)处理图片的方式: 如果ListView中自定义的Item中有涉及到大量图片的,一定要对图片进行细心的处理,因为图片占的内存是 ListView 项中最头疼的,处理图片的方法大 ...
- Android进阶笔记15:选用合适的IPC方式
1. 相信大家都知道Android进程间通信方式很多,比如AIDL.Messenger等等,接下来我就总结一下这些IPC方式优缺点. 2. IPC方式的优缺点和适用场景 3. 附加:使用Intent实 ...
- Android进阶笔记:Messenger源码详解
Messenger可以理解为一个是用于发送消息的一个类用法也很多,这里主要分析一下再跨进程的情况下Messenger的实现流程与源码分析.相信结合前面两篇关于aidl解析文章能够更好的对aidl有一个 ...
- Android进阶笔记:AIDL内部实现详解 (二)
接着上一篇分析的aidl的流程解析.知道了aidl主要就是利用Ibinder来实现跨进程通信的.既然是通过对Binder各种方法的封装,那也可以不使用aidl自己通过Binder来实现跨进程通讯.那么 ...
- android学习笔记12——ListView、ListActivity
ListView.ListActivity ==> ListView以垂直列表的形式显示所有列表项. 创建ListView的方式: 1.直接使用ListView创建 2.Activity继承Li ...
- Android进阶笔记16:ListView篇之ListView刷新显示(全局 和 局部)
一.ListView内容变化后,动态刷新的步骤(全局刷新): (1)更新适配器Adapter数据源:(不要使用匿名内部类) (2)调用适配器Adapter的刷新方法notifyDataSetChang ...
- Android进阶笔记13:ListView篇之ListView刷新显示(全局 和 局部)
一.ListView内容变化后,动态刷新的步骤(全局刷新): (1)更新适配器Adapter数据源:(不要使用匿名内部类) (2)调用适配器Adapter的刷新方法notifyDataSetChang ...
- Android进阶笔记14:ListView篇之ListView性能优化
1. 首先思考一个问题ListView如何才能提高效率 ? 当convertView为空时候,用setTag()方法为每个View绑定一个存放控件的ViewHolder对象.当convertView不 ...
- Android进阶笔记11:ListView篇之ListView显示多种类型的条目(item)
ListView可以显示多种类型的条目布局,这里写显示两种布局的情况,其他类似. 1. 这是MainActivity,MainActivity的布局就是一个ListView,太简单了这里就不写了,直接 ...
随机推荐
- vs2012不能打开项目解决办法
只要卸载这两个不定就能解决问题.
- 第二百四十二天 how can I 坚持
今天... 貌似没啥啊. 第一天带帽子上班. 还有回来买了两个柚子吃了,有点上火啊. 还有今天雾霾爆表啊,pm2.5 600多啊. 还有看了部电影<蚁人>,挺好看.希望不会出二.三.四. ...
- CalendarUtil
package ch.makery.address.util; import java.text.ParseException; import java.text.SimpleDateFormat; ...
- HDU 2275 multiset
题意:n个操作 Push 入容器 Pop弹出一个 满足<=该数的最大的数(若没有输出No Element!) 开始用set打了一遍wrong了,这里入容器的数是有重复的,所以用multiset ...
- C++ API设计
<C++ API设计> 基本信息 作者: (美)Martin Reddy 译者: 刘晓娜 臧秀涛 林健 丛书名: 图灵程序设计丛书 出版社:人民邮电出版社 ISBN:97871153 ...
- jeecms支持的freemaker标签大全
<@e.form id="jvForm" action="o_add.do"> <@e.text label="字段名" ...
- iOS开发代码规范
1.关于命名 1.1统一要求 含义清楚, 尽量做到不需要注释也能了解其作用,若做不到,就加注释 使用全称不使用缩写 1.2类的命名 大驼峰式命名:每一个单词的首字母都采用大写字母例子: MFHomeP ...
- C#学习笔记(五):泛型
认识泛型 泛型使类型参数化,从而实现了算法上的代码重用. 同时由于去掉了转换中装箱和拆箱的操作,使用泛型还可以提高程序的运行速度. 我们先看看C#自带的使用了泛型的类: using System.Co ...
- DBMS_LOB
1.LOB背景 在现在的系统开发中,需要存储的已不仅仅是简单的文字信息,也包括一些图片.音像资料或者超长的文本,这要求后台数据库具有存储这些数据的能力,Oracle通过提供LOB对象实现了该功能. 2 ...
- 十,选择cfee编辑器并学会调试程序。以及结束语。
为什么推荐用cfree呢?因为我认为这个编辑器界面友好,用起来方便. 你也许会问,调试程序是什么? 那么下面思考几个问题:对于前面讲的分支结构和循环结构有点不懂怎么办?如果写的程序语法没有错误但是运算 ...