画布:尝试使用回收的位图错误

时间:2017-05-03 09:28:18

标签: android android-layout bitmap android-asynctask

我是一个相当新的程序员,所以任何建议将不胜感激。我有一个类,每次调用时都在循环中运行AsyncTask。 AsyncTask看起来像这样:

public class LoadImageTask extends AsyncTask<Void, Void, Void> {

    Context c;
    ViewHolder vh;
    public Bitmap bm;
    ViewGroup container;
    LinearLayout layout;

    public LoadImageTask(Context c, ViewHolder vh, ViewGroup container, 
    LinearLayout linlay) {

        this.vh = vh;
        this.c = c;
        this.container = container;
        this.layout = linlay;
    }

    protected Void doInBackground(Void... params) {
        Tools tools = new Tools();
        this.bm = tools.getAlbumart(this.c, vh.albumID);
        return null;
    }

    protected void onPostExecute(Void param) {
        vh.iv.setImageBitmap(this.bm);
        this.layout.addView(this.container);
        if (bm!=null) {
            bm.recycle();
        }

    }
}

ViewHolder vh - 包含2个textview和Imageview的类

ViewGroup容器 - 用于扩充我所做的xml设计的容器(带有2个textviews和一个ImageView)

LinearLayout linlay - 我正在添加容器的滚动视图布局(根据我在该视图中需要的元素数量进行扩展)

我使用太多内存创建的位图,所以我想回收它们,但每次我在将容器添加到布局后尝试回收它们时,它说我正在尝试使用回收的位图(当我在将容器添加到屏幕后清楚地调用回收时... ...我在这一点上很难过。任何帮助都会很好。

2 个答案:

答案 0 :(得分:3)

目前,在将位图渲染到UI之前回收位图,因为setImageBitmap(bm)只会准备ImageView以渲染提供的位图。渲染将被安排用于UI的下一次失效。

在呈现位图之前调用

bm.recycle(),因此在尝试绘制位图时应用程序将崩溃。

在UI中使用Bitmap时无法回收Bitmap,Bitmap必须保留在内存中。在大多数情况下,Android会处理回收很好,但是如果你需要自己回收,你需要确保之后不再使用Bitmap实例(在这种情况下稍后将呈现Bitmap实例)。

答案 1 :(得分:0)

  1. 如果位图使用太多内存,您应该尝试将其缩小! (例如:具有256x256的Albumart是不错的选择)

  2. 如果您在Android 3.0及更高版本上运行应用程序,则无需调用recycle(),因为GC会完美地处理它。

  3. 请参阅PärNilsAmsen的回答。