首先说一下,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);


   当我们下滑动后,然后在上滑动的时候软应用起到了效果,效率很快哦,可以和新浪聘美了,呵呵,玩笑,要优化的地方还很多.