我是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()不会被调用,因此原始位图停留在内存中。我更改了可见的可见性,现在一切正常。