ListView如何加载网络图片,防止内存溢出
2014-02-10 16:50
274 查看
首先是源代码的下载地址:http://download.csdn.net/detail/iloveyoueveryday/6910147 。
打开源码,可以看到:
然后来看源代码的目录,再介绍ListView之前,先说一些准备工作。
Cache类是为图片缓存准备的,此程序会把网络图片存在SD卡的.klcz目录下(使用FileHandler类进行操作),然后将图片信息存到本地数据库(使用CacheHandler类进行操作),并将长期(比如7天)未使用的图片缓存删除。
Cache类的属性如下:
Session类是一个单例类,主要用于存储全局数据。我最初创建他是为了方便存储和修改常用的登录后的用户数据。但现在发现,他的用处很大,这里也略微用到了一点,就拿过来直接用了。
然后开始介绍重点。
首先是ImageResource单例类,这个类是用来加载图片资源的。它使用LruCache将加载的图片资源进行保存,下次使用时直接拿出来用,无需重复加载,并且能够管理内存,当图片多于预先设置的最大可使用内存时,它会将最长时间未使用的图片内存释放掉,从而节约内存。此程序通过本类来加载本地和网络图片。(ImageResource类还提供了别的有用的功能,是我花了好长时间写的,仅供大家参考)
接下来距离正题更近一步了。看看这个内部类:
ViewHolder是自定义的内部类。大家都知道,当你上拉或者下拉ListView的时候,都会重新加载新出现的Item的getView方法,如果每次执行getView方法,都重新加载布局,肯定会浪费时间和内存,ViewHolder就是为了防止重新加载布局而建立的。接下来会说到它的用法。
下面看核心代码,getView方法:
代码注释很清晰,这里就不多做解释,只说一些注意事项。首先是本地的图片也要用ImageResource加载,才能保证每个图片只加载一次,不浪费资源和内存。其次,也是最重要的,虽然不用每次重新加载布局,但是有必要将图片重新设置成默认的,表示原来的图片暂不使用了,以便系统能够在内存使用过大时及时收回当前界面不使用的图片。
当然,本人能力有限,如果优化的不够好,欢迎网友指出,我一定会努力改正。
打开源码,可以看到:
然后来看源代码的目录,再介绍ListView之前,先说一些准备工作。
Cache类是为图片缓存准备的,此程序会把网络图片存在SD卡的.klcz目录下(使用FileHandler类进行操作),然后将图片信息存到本地数据库(使用CacheHandler类进行操作),并将长期(比如7天)未使用的图片缓存删除。
Cache类的属性如下:
/** 数据库中的ID */ private int id; /** 图片的网络路径 */ private String picture; /** 保存路径 */ private String local; /** 更新时间 */ private Date update_time;
Session类是一个单例类,主要用于存储全局数据。我最初创建他是为了方便存储和修改常用的登录后的用户数据。但现在发现,他的用处很大,这里也略微用到了一点,就拿过来直接用了。
然后开始介绍重点。
首先是ImageResource单例类,这个类是用来加载图片资源的。它使用LruCache将加载的图片资源进行保存,下次使用时直接拿出来用,无需重复加载,并且能够管理内存,当图片多于预先设置的最大可使用内存时,它会将最长时间未使用的图片内存释放掉,从而节约内存。此程序通过本类来加载本地和网络图片。(ImageResource类还提供了别的有用的功能,是我花了好长时间写的,仅供大家参考)
接下来距离正题更近一步了。看看这个内部类:
class ViewHolder { public TextView text; public ImageView image; }
ViewHolder是自定义的内部类。大家都知道,当你上拉或者下拉ListView的时候,都会重新加载新出现的Item的getView方法,如果每次执行getView方法,都重新加载布局,肯定会浪费时间和内存,ViewHolder就是为了防止重新加载布局而建立的。接下来会说到它的用法。
下面看核心代码,getView方法:
@Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder = null; if(convertView == null){ // 不存在则加载新布局 LayoutInflater inflater = (LayoutInflater) parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = inflater.inflate(R.layout.item_pic_list, null); holder = new ViewHolder(); holder.text = (TextView) convertView.findViewById(R.id.item_title); holder.image = (ImageView) convertView.findViewById(R.id.item_image); convertView.setTag(holder); } else { // 存在则加载原来布局,布局重用,无需重复加载 holder = (ViewHolder) convertView.getTag(); } int no = position + 1; holder.text.setText("图片列表测试:" + no); // ir是i5suoi库中ImageResource的实例,专门负责单例加载图片资源,并及时释放长时间不用的图片内存 // 先设置成默认图片,以便能够将列表中不显示在屏幕上的图片及时回收 holder.image.setImageBitmap(ir.getBitmap(getResources(), R.drawable.ic_launcher)); // 加载并显示网络图片,每个图片只加载一次,然后存到本地缓存 ir.getBitmap(holder.image, pic.replace("_num", "" + no % 60), holder.image.getWidth(), holder.image.getHeight()); return convertView; }
代码注释很清晰,这里就不多做解释,只说一些注意事项。首先是本地的图片也要用ImageResource加载,才能保证每个图片只加载一次,不浪费资源和内存。其次,也是最重要的,虽然不用每次重新加载布局,但是有必要将图片重新设置成默认的,表示原来的图片暂不使用了,以便系统能够在内存使用过大时及时收回当前界面不使用的图片。
当然,本人能力有限,如果优化的不够好,欢迎网友指出,我一定会努力改正。
相关文章推荐
- Android学习笔记_51_转android 加载大图片防止内存溢出
- android 加载图片防止内存溢出
- 如何解决加载大图片时内存溢出的问题
- 如何解决加载大图片时内存溢出的问题
- Android开发中如何解决加载大图片时内存溢出的问题
- Android 如何实现ListView异步加载网络图片
- Android开发中如何解决加载大图片时内存溢出的问题
- android 加载大图片防止内存溢出
- Android开发中如何解决加载大图片时内存溢出的问题
- 解决listview加载图片内存溢出的方案
- 如何解决加载大图片时内存溢出的问题
- Android开发中如何解决加载大图片时内存溢出的问题
- Android开发中如何解决加载大图片时内存溢出的问题
- 如何解决加载大图片时内存溢出的问题 OOM
- 如何解决加载大图片时内存溢出的问题
- Android:ListView异步加载图片(实现网络下载、存储本地、缓存内存、压缩显示)
- Android开发中如何解决加载大图片时内存溢出的问题
- android 加载图片防止内存溢出
- Android开发中如何解决加载大图片时内存溢出的问题
- android 加载大图片防止内存溢出