首先说一下,android系统加载大量图片系统内存溢出的3中解决方法:

(1)从网络或本地加载图片的时候,只加载缩略图。这个方法的确能够少占用不少内存,可是它的致命的缺点就是,因为加载的是缩略图,所以图片失真比较严重,对于对图片质量要求很高的应用,可以采用下面的方法

/**

*按照图片路径加载

*@param path图片资源的存放路径

*@param scalSize缩小的倍数

*@return

*/

public static Bitmap loadResBitmap(String path, int scalSize){

  BitmaoFactory.Options options = new BitmapFactory.Options();

  options.inJustDecodeBounds = false;

  options.inSampleSize = scalSize;

  Bitmap bmp = BitmapFactory.decodeFile(path, options);

  reuturn bmp;

}

(2)运用JAVA的软引用,进行图片缓存,将经常需要加载的图片,存放在缓存里,避免反复加载。

(3)及时销毁不再使用的Bitmap对象。

if (bitmap != null && b!itmap.isRecycled()){

  bitmap.recycle();

  bitmap = null; // recycle()是个比较漫长的过程,设为null,然后在最后调用System.gc(),效果能好很多

  System.gc();

}

好了,以上是主题之前的知识补充,以下是这篇blog的主要内容。HashMap<String, SoftReference<Drawable>> imageCache 关于SoftReference这个类多少知道些机制,只是处在会用的阶段(这是不够的)。

机制:简单来说,她会帮助我们管理内存,防止内存溢出,另外一点也就相当于map,临时缓存些图片drawable让我们可以直接引用,很好了解决了OOM异常.

实现代码片段:

[java]
package com.Tianyou.Mobile.Common; 
 
import java.io.IOException; 
import java.io.InputStream; 
import java.lang.ref.SoftReference; 
import java.net.MalformedURLException; 
import java.net.URL; 
import java.util.HashMap; 
 
import com.Tianyou.Mobile.Util.MyUtil; 
 
import android.graphics.Bitmap; 
import android.graphics.drawable.BitmapDrawable; 
import android.graphics.drawable.Drawable; 
import android.os.Handler; 
import android.os.Message; 
 
/***
 * 异步加载图片 缓存的实现
 * 
 * @author jia
 * 
 */ 
public class AsyncImageLoader { 
    // 软引用 
    private HashMap<String, SoftReference<Drawable>> imageCache; 
 
    public AsyncImageLoader() { 
        imageCache = new HashMap<String, SoftReference<Drawable>>(); 
    } 
 
    /***
     * 下载图片
     * 
     * @param imageUrl
     *            图片地址
     * @param imageCallback
     *            回调接口
     * @return
     */ 
    public Drawable loadDrawable(final String imageUrl, 
            final ImageCallback imageCallback) { 
        if (imageCache.containsKey(imageUrl)) { 
            SoftReference<Drawable> softReference = imageCache.get(imageUrl); 
            Drawable drawable = softReference.get(); 
            if (drawable != null) { 
                return drawable; 
            } 
        } 
        final Handler handler = new Handler() { 
            public void handleMessage(Message message) { 
                imageCallback.imageLoaded((Drawable) message.obj, imageUrl); 
            } 
        }; 
        // 开启线程下载图片 
        new Thread() { 
            @Override 
            public void run() { 
                Drawable drawable = loadImageFromUrl(imageUrl); 
                // 将下载的图片保存至缓存中 
                imageCache.put(imageUrl, new SoftReference<Drawable>(drawable)); 
                Message message = handler.obtainMessage(0, drawable); 
                handler.sendMessage(message); 
            } 
        }.start(); 
        return null; 
    } 
 
    /***
     * 根据URL下载图片(这里要进行判断,先去本地sd中查找,没有则根据URL下载,有则返回该drawable)
     * 
     * @param url
     * @return
     */ 
    public static Drawable loadImageFromUrl(String imageURL) { 
 
        Bitmap bitmap = MyUtil.GetBitmap(imageURL, 100); 
        Drawable drawable = new BitmapDrawable(bitmap); 
        return drawable; 
 
    } 
 
    // 回调接口 
    public interface ImageCallback { 
        public void imageLoaded(Drawable imageDrawable, String imageUrl); 
    } 
 

     上面这个类斯通见惯了,大部分都是这样实现的,我现在要讲一点,也是迷惑我很久了一点(回调接口运用)本人基础不好,所以卡在这里了,
     在listview中的getview方法中要调用这个方法:

代码片段:

[java] 
public Drawable getDrawable(AsyncImageLoader asyncImageLoader, 
            String imageUrl, final ImageView imageView) { 
        Drawable drawable = asyncImageLoader.loadDrawable(imageUrl, 
                new ImageCallback() { 
                    @Override 
                    public void imageLoaded(Drawable imageDrawable, 
                            String imageUrl) { 
                        if (imageDrawable != null) 
                            imageView.setImageDrawable(imageDrawable); 
                        else 
                            imageView.setImageResource(R.drawable.u6_normal); 
                    } 
                }); 
        return drawable; 
    } 
  这个方法作用:获取软用中的图片,其实在我们首次进入listview中的时候,软应用是不起作用的,只是用来下载图片保存至sd卡和软引用中.这个方法就是执行了这些操作,对于参数imageView 就是在要把获取的drawable设置进去.
  
执行的顺利:首先我们调用的是loadDrawable这个方法,然后查找软引用中有没有该drawable,没有的话则线程下载,下载ok后会执行
handleMessage中imageCallback.imageLoaded((Drawable) message.obj,
imageUrl);然后执行我们已经实现了这个接口.

在getiview 中执行代码片段:

[java] 
Drawable drawable = getDrawable(asyncImageLoader, Image_L, 
                holder.iv_image); 
         
        if(drawable!=null) 
            holder.iv_image.setImageDrawable(drawable); 
   当我们下滑动后,然后在上滑动的时候软应用起到了效果,效率很快哦,可以和新浪聘美了,呵呵,玩笑,要优化的地方还很多.

PS:其次,可参考http://www.2cto.com/kf/201303/194546.html

android Listview 软引用SoftReference异步加载图片的更多相关文章

  1. 软引用SoftReference异步加载图片

    HashMap<String, SoftReference<Drawable>> imageCache 关于SoftReference这个类多少知道些机制,会用就ok了. 机制 ...

  2. Android 实现ListView异步加载图片

    ListView异步加载图片是非常实用的方法,凡是是要通过网络获取图片资源一般使用这种方法比较好,用户体验好,下面就说实现方法,先贴上主方法的代码: package cn.wangmeng.test; ...

  3. Android之ListView异步加载图片且仅显示可见子项中的图片

    折腾了好多天,遇到 N 多让人崩溃无语的问题,不过今天终于有些收获了,这是实验的第一版,有些混乱,下一步进行改造细分,先把代码记录在这儿吧. 网上查了很多资料,发现都千篇一律,抄来抄去,很多细节和完整 ...

  4. 又优化了一下 Android ListView 异步加载图片

    写这篇文章并不是教大家怎么样用listview异步加载图片,因为这样的文章在网上已经有很多了,比如这位仁兄写的就很好: http://www.iteye.com/topic/685986 我也是因为看 ...

  5. Android中ListView异步加载图片错位、重复、闪烁问题分析及解决方案

    我们在使用ListView异步加载图片的时候,在快速滑动或者网络不好的情况下,会出现图片错位.重复.闪烁等问题,其实这些问题总结起来就是一个问题,我们需要对这些问题进行ListView的优化. 比如L ...

  6. Android的ListView异步加载图片时,错位、重复、闪烁问题的分析及解决方法

    Android ListView异步加载图片错位.重复.闪烁分析以及解决方案,具体问题分析以及解决方案请看下文. 我们在使用ListView异步加载图片的时候,在快速滑动或者网络不好的情况下,会出现图 ...

  7. android listview 异步加载图片并防止错位

    网上找了一张图, listview 异步加载图片之所以错位的根本原因是重用了 convertView 且有异步操作. 如果不重用 convertView 不会出现错位现象, 重用 convertVie ...

  8. android异步加载图片并缓存到本地实现方法

    图片过多造成内存溢出,这个是最不容易解决的,要想一些好的缓存策略,比如大图片使用LRU缓存策略或懒加载缓存策略.今天首先介绍一下本地缓存图片     在android项目中访问网络图片是非常普遍性的事 ...

  9. ListView异步加载图片

    ListView异步加载图片是非常实用的方法,凡是是要通过网络获取图片资源一般使用这种方法比较好,用户体验好,下面就说实现方法,先贴上主方法的代码: package cn.wangmeng.test; ...

随机推荐

  1. [转] 浏览器自动化测试初探:使用 phantomjs 与 casperjs

    [From] https://www.qcloud.com/community/article/641602001489391648 作者:yangchunwen 首先要解释一下为什么叫浏览器自动化测 ...

  2. Putty使用帐号和密码的自动登录

    Putty使用ssh key做验证登陆是最方便的,不用密码.如果不想做key exchange,只是单纯想保存帐号密码做自动登陆,可以借助bat文件的方式如下,其中MyServer是已经保存了的ses ...

  3. hdu-1702-栈和队列

    ACboy needs your help again! Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ( ...

  4. maven的resources插件

    <build><sourceDirectory>src/jvm</sourceDirectory> <testSourceDirectory>test/ ...

  5. window.open打开窗口的几种方式

    1. 在当前窗口打开百度,并且使URL地址出现在搜索栏中. window.open("http://www.baidu.com/", "_search"); w ...

  6. ansile 命令解释选项

    1, -a MODULE_ARGS --args=MODULE_ARGS 作用传递参数给模块使用 2, --ask-vault-pass 执行时询问vault的密码 3, -B SECONDS --b ...

  7. SEO艺术阅读笔记

      SEO(Search Engine Optimization)搜索引擎优化 搜索引擎:反映认知,连接贸易搜索引擎基础百度搜索高级语法确定SEO目标,定义网站受众设定SEO目标开发前定制SEO方案理 ...

  8. java连接redis使用jedis带密码

    一.引入jedis的Maven配置文件 <!-- redis连接客户端jedis --> <dependency> <groupId>redis.clients&l ...

  9. 最好用的数据存储Easy Save2讲解

    转载:http://www.manew.com/thread-100109-1-1.html   今天抽时间学习了“Easy Save2”插件,版本v2.6.3  我个人觉得这个插件是做数据存取最好的 ...

  10. URAL ——1249——————【想法题】

     Ancient Necropolis Time Limit:5000MS     Memory Limit:4096KB     64bit IO Format:%I64d & %I64u ...