Listma的位图内存不足

时间:2014-01-18 16:12:44

标签: android bitmap out-of-memory

我让用户在ImageView上绘制内容并单击“保存”以保存绘图。之后,用户可以在ListView中查看所有已保存的图形,这些图形具有ImageView和两个带有一些视图的TextView。

为了避免保存和检索位图,我存储了在txt文件中绘制的所有xy点,并在使用createBitmap方法填充列表时重新创建位图,绘制点并在适配器内的ImageView上设置位图。

当用户删除或更新列表时,我完成并重新启动列表活动以重新加载文件,并重新创建所有这些位图,但之前不会回收,因为我不知道在哪里调用回收方法!!

所以很自然地问题是,由于所有的位图,有时我会得到OutOfMemory错误。 问题:我在哪里可以为位图调用回收,或者如何在不使用这么多内存的情况下实现这一点 这是列表适配器

public class CustomGalleryListAdapter extends ArrayAdapter<String>{
private final Activity context;
private final String[] name_plus_details;
private final String[] imageinfo;
public CustomGalleryListAdapter(Activity context,
String[] name_plus_details, String[] imageinfo) {
super(context, R.layout.gallery_list_single_item_layout, name_plus_details);
this.context = context;
this.name_plus_details = name_plus_details;
this.imageinfo = imageinfo;
}
@Override
public View getView(int position, View view, ViewGroup parent) {
    Paint mPaint,mPaint2;
    mPaint = new Paint();
    mPaint.setAntiAlias(true);
    mPaint.setDither(true);
    mPaint.setColor(Color.BLUE);
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setStrokeJoin(Paint.Join.ROUND);
    mPaint.setStrokeCap(Paint.Cap.ROUND);
    mPaint.setStrokeWidth(23/4);

    mPaint2 = new Paint();
    mPaint2.setAntiAlias(true);
    mPaint2.setDither(true);
    mPaint2.setColor(Color.GREEN);
    mPaint2.setStyle(Paint.Style.STROKE);
    mPaint2.setStrokeJoin(Paint.Join.ROUND);
    mPaint2.setStrokeCap(Paint.Cap.ROUND);
    mPaint2.setStrokeWidth(17/4);


    LayoutInflater inflater = context.getLayoutInflater();
    Bitmap mBitmap = Bitmap.createBitmap(600/5, 700/5, Bitmap.Config.ARGB_8888);
    Canvas mCanvas = new Canvas(mBitmap);
    String[] imagedata = imageinfo[position].split(":");
    String[] points;
    for(int i=0;i<imagedata.length;i++){
        if(imagedata[i].contains(";")){
            points=imagedata[i].split(";");
            if(points[0].length()>0){
                int drawx1 = Integer.parseInt(points[0].split(",")[0]);
                int drawy1 = Integer.parseInt(points[0].split(",")[1]);
                mCanvas.drawCircle(drawx1/5, drawy1/5, 15/4, mPaint2);
            }
            for(int h=0;h+1<points.length-1;h++){
                int drawx1 = Integer.parseInt(points[h].split(",")[0]);
                int drawy1 = Integer.parseInt(points[h].split(",")[1]);
                int drawx2 = Integer.parseInt(points[h+1].split(",")[0]);
                int drawy2 = Integer.parseInt(points[h+1].split(",")[1]);
                mCanvas.drawLine(drawx1/5, drawy1/5, drawx2/5, drawy2/5, mPaint);
            }
        }
    }
    View rowView= inflater.inflate(R.layout.gallery_list_single_item_layout, null, true);
    TextView detailsTextView = (TextView) rowView.findViewById(R.id.txt);
    TextView name_field = (TextView) rowView.findViewById(R.id.gallery_name_field);

    ImageView imageView = (ImageView) rowView.findViewById(R.id.img);
    imageView.setImageDrawable(new BitmapDrawable(getContext().getResources(),mBitmap));
    imageView.setScaleType(ImageView.ScaleType.FIT_XY);      
    imageView.setBackgroundColor(Color.GRAY);
    String[] text_parts = name_plus_details[position].split("ENDNAME");
    name_field.setText(text_parts[0]);
    detailsTextView.setText("\n"+text_parts[1]);

    return rowView;

}
}

2 个答案:

答案 0 :(得分:0)

尝试使用持有者,这样就不会为每个单元格充气,因为您只是重复使用它们。看看这个:http://developer.android.com/training/improving-layouts/smooth-scrolling.html#ViewHolder 网上还有大量的例子告诉你如何在ArrayAdapter中使用持有者

答案 1 :(得分:0)

首先 - 阅读本文: http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html

我认为,根据我的理解,它可以为你的位图制作像地图集这样的东西,这样可以节省很多内存 - 这看起来好多了。

使用此解决方案将为您提供一种处理位图的非常方便的方法: http://developer.android.com/reference/android/util/LruCache.html#entryRemoved(boolean,K,V,V)