私は、実際には何も存在しないという問題に遭遇するまで、stackoverflowに頻繁にゲストとして参加していました。だからここに私の最初の質問があります:
次のステップに進む前に、ユーザーが複数の写真を撮ることができるカメラアプリを構築しています。カメラステージでスタイリングしながら写真を確認および削除できるようにしたいので、削除ボタンを使用して、すでにキャプチャされた画像のサムネイルを表示するカスタムビューを作成しました。これらの「Thumbviews」は、camerapreview-SurfaceViewの上部にあるLinearLayoutに含まれており、デフォルトの可視性は「GONE」です。ユーザーはボタンで表示を切り替えることができます。
すべて正常に動作しますが、問題が1つあります。約10枚以上の写真を撮ると、OutOfMemoryErrorが発生します。サムネイルは非常に小さく、メモリをあまり消費しません。また、元のビットマップをリサイクルし、サムネイルを作成した後にSystem.gc()を実行します。奇妙なことに、含まれているLinearLayoutの可視性を「VISIBLE」に設定し、再び「GONE」に設定するボタンを押すと、明らかにすべてのメモリが解放され、10枚よりも多くの写真を撮ることができます。切り替えてみましたコードでの可視性は機能しませんが、描画キャッシュも破壊されます。可視性ボタンを2回押す以外に、そのメモリを解放する別の方法が必要です;-)
ThumbViewのコードは次のとおりです。
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);
}
}