android listview 图片 内存溢出 解决方案

package com.testmemoryadapter;  
  
import java.util.ArrayList;  
  
import android.content.Context;  
import android.graphics.Bitmap;  
import android.graphics.BitmapFactory;  
import android.util.Log;  
import android.view.LayoutInflater;  
import android.view.View;  
import android.view.ViewGroup;  
import android.widget.BaseAdapter;  
import android.widget.ImageView;  
  
public class TestAdapter extends BaseAdapter {  
  
    private ArrayList list;  
    private LayoutInflater mInflater;  
    private Context context;  
    //这个用来保存 imageview 的引用  
    private ArrayList viewList = new ArrayList();  
    //这个用来 保存 bitmap  
    private ArrayList bitmapList = new ArrayList();  
  
    @Override  
    public int getCount() {  
        // TODO Auto-generated method stub  
        return list.size();  
    }  
  
    @Override  
    public Object getItem(int arg0) {  
        // TODO Auto-generated method stub  
        return null;  
    }  
  
    @Override  
    public long getItemId(int arg0) {  
        // TODO Auto-generated method stub  
        return 0;  
    }  
  
    public TestAdapter(Context context, ArrayList list) {  
        super();  
        this.context = context;  
        this.mInflater = LayoutInflater.from(context);  
        this.list = list;  
    }  
  
    @Override  
    public View getView(int position, View convertView, ViewGroup arg2) {  
        // TODO Auto-generated method stub  
  
        convertView = mInflater.inflate(R.layout.test_list_row, null);  
  
        ImageView iv = (ImageView) convertView.findViewById(R.id.imageView);  
          
          
        //用try catch 块包围住  
        try {  
            setImage(iv);  
        } catch (OutOfMemoryError e) {  
            // 这里就是当内存泄露时 需要做的事情  
            e.printStackTrace();  
  
            Log.d("memory", "out");  
              
            //释放内存资源  
            recycleMemory();  
              
            //将刚才 发生异常没有执行的 代码 再重新执行一次  
            setImage(iv);  
  
        }  
  
        return convertView;  
    }  
  
      
    //这里是关键  
    private void recycleMemory() {  
        //一屏显示多少行 这里就设置为多少。不设也行 主要是用户体验好 不会将用户看到的图片设为默认图片  
        int showCount = 10;  
          
        //  
        for (int i = 0; i < viewList.size()-showCount; i++) {  
            ImageView iv = (ImageView) viewList.get(i);  
            /*** 
             *  这里是关键! 将 imageview 设置一张默认的图片 , 
             *  用于解决当释放bitmap的时候 还有其他 控件对他保持引用 
             *  就不会发生trying to use a recycled bitmap异常了 
             */  
            iv.setImageResource(R.drawable.default_cover);  
            //从list中去除  
            viewList.remove(i);  
        }  
  
//      viewList = new ArrayList();  
  
        for (int i = 0; i < bitmapList.size()-10; i++) {  
  
            Bitmap bitmap = (Bitmap) bitmapList.get(i);  
            //这里就开始释放bitmap 所占的内存了  
            if (!bitmap.isRecycled()) {  
                bitmap.recycle();  
                System.out.println("recycle ");  
            }  
            //从list中去除  
            bitmapList.remove(i);  
        }  
  
//      bitmapList = new ArrayList();  
    }  
      
    private void setImage(ImageView iv){  
        /*** 
         * 从sdcard获取 图片  这张图片 只要不超过  android对于图片大小的限制即可  
         * 我用了 一张比较大的图片 也通过测试 
         */  
        Bitmap bitmap = BitmapFactory.decodeFile("/sdcard/test/1.jpg");  
  
        iv.setImageBitmap(bitmap);  
          
        //将这个控件 添加到 list里  
        viewList.add(iv);  
        //将要 释放的 bitmap也添加到list里  
        bitmapList.add(bitmap);  
    }  
  
}  

  

posted on 2012-10-25 02:33  南海菜园  阅读(656)  评论(0编辑  收藏  举报

导航