带有Android位图的奇怪的OutofMemoryError:为什么显示并隐藏包含视图避免使用



我是Stackoverflow的常客,直到我遇到一个我真的找不到存在的问题。所以这是我的第一个问题:

我正在构建一个相机应用程序,在该应用程序中,用户可以在下一步之前拍摄几张照片。我想为用户提供在相机舞台上进行造型时查看和删除图片的可能性,因此我写了一个自定义视图,以显示已捕获的图像的缩略图,并使用删除按钮。这些"拇指景"包含在位于camerapreview-surfaceview顶部的线性层状中,并具有" gone"的默认可见性。用户可以使用按钮切换可见性。

这一切都很好,但是我有一个问题:当我拍摄大约10张图片时,我会得到一张OutofMemoryError。缩略图确实很小,并且不需要很多内存,而且我还回收原始位图并在创建拇指后执行System.gc()。奇怪的是,当我按按下将包含线度的可见性设置为"可见"的按钮,然后再次释放到"可见",显然所有的内存都被释放了,我可以拍摄比10的图片更多的图片。我尝试切换代码中的可见性,但这不起作用,并且也破坏了绘图缓存。除了2次按下我的可见性按钮外,还必须有另一种方法来释放该内存; - )

这是拇指浏览的代码:

public class ThumbView extends View {
private Bitmap mBitmap;
private Bitmap mScaledBitmap;
private int mWidth, mHeight, mPosX, mPosY;
static private Bitmap mDeleteBitmap;
private File mPreviewFile;
private File mFinalFile;
private Orientation mOrientation;
private boolean mRed;
public ThumbView(Context context, Bitmap bitmap, File previewFile, File finalFile, Orientation orientation) {
    super(context);
    mBitmap = bitmap;
    mPreviewFile = previewFile;
    mFinalFile = finalFile;
    mOrientation = orientation;
    if(mDeleteBitmap != null)
        return;
    mDeleteBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.deletebutton);
}
public void deleteFile()
{
    if(mPreviewFile != null && mPreviewFile.exists())
    {
        mPreviewFile.delete();
    }
    if(mFinalFile != null && mFinalFile.exists())
    {
        mFinalFile.delete();
    }
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    mWidth  = MeasureSpec.getSize(widthMeasureSpec);
    setMeasuredDimension(mWidth, mWidth);
    if(mBitmap == null)
        return;
    mHeight = mWidth;
    float bitmapRatio = mBitmap.getWidth() / (float) mBitmap.getHeight();
    if(bitmapRatio > 1)
    {
        mScaledBitmap = Bitmap.createScaledBitmap(mBitmap, mWidth,
                (int)(mWidth/bitmapRatio), true);
        mPosY = (mWidth-mScaledBitmap.getHeight())/2;
    }
    else
    {
        mScaledBitmap = Bitmap.createScaledBitmap(mBitmap, (int)(mHeight*bitmapRatio),
                mHeight, true);
        mPosX = (mHeight-mScaledBitmap.getWidth())/2;
    }

    Matrix mtx = new Matrix();
    mtx.postRotate(-90);
    Bitmap b = Bitmap.createBitmap(mScaledBitmap, 0, 0, mScaledBitmap.getWidth(), mScaledBitmap.getHeight(), mtx, true);
    mScaledBitmap = b;
    b = null;
    mBitmap.recycle();
    mBitmap = null;
    System.gc();
}
public boolean deleteButtonPressed(float x, float y)
{
    Rect r = new Rect(mPosY, mPosX, mPosY+mDeleteBitmap.getWidth(),
            mPosX+mDeleteBitmap.getHeight());
    if(r.contains((int)x, (int)y))
    {
        return true;
    }
    return false;
}
public void setRed(boolean red)
{
    mRed = red;
    invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
    canvas.drawBitmap(mScaledBitmap, mPosY, mPosX, new Paint());
    canvas.drawBitmap(mDeleteBitmap, mPosY, mPosX, new Paint());
    if(mRed)
        canvas.drawColor(0x55FF0000);
}

}

"为什么不断开"答案很容易。当设置儿童视图(或容器)的可见性消失时,父母的布局(通常)将跳过它,甚至不费心渲染它。它不是"隐藏的",根本不存在。

如果您的缩略图确实是缩略图,则您不应该用完记忆,但是,我认为您不会降采用它们(我可能错了)。您如何向他们展示?您应该分享该代码。(新照片 ->缩略图图像 ->图像视图)

我很愚蠢。显然,当视图消失时,我的onMeasure()不会被调用,因此原始位图停留在内存中。我更改了可见的可见性,现在一切正常。

相关内容

  • 没有找到相关文章