2
私はアプリを開発しようとしました。これは小さい101KBの画像ファイルでは問題ありませんが、この画像の代わりに307KBの画像でこのアプリを使用すると、実行されずに表示されます:java.lang.OutOfMemoryError:ビットマップサイズがVMの予算を超えています。続きjava.lang.OutOfMemoryErrorと呼ばれるメモリリークを回避する方法:ビットマップサイズがandroidのVM予算を超えています
が私のコードです:
Resources rs = getResources();
Drawable dw = rs.getDrawable(R.drawable.chart);
width = dw.getIntrinsicWidth();
height = dw.getIntrinsicHeight();
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
fitScaleX = (float)dm.widthPixels/(float)width;
fitScaleY = fitScaleX;
とラインで、Drawable dw = rs.getDrawable(R.drawable.chart);
エラーが発生します。どうすればこの問題を回避できますか?
これは私の完全なコードです:ビットマップ画像は大量のメモリを消費する
public class ZoomActivity extends Activity implements OnTouchListener {
ImageView view;
Matrix matrix = new Matrix();
Matrix savedMatrix = new Matrix();
PointF start = new PointF();
PointF mid = new PointF();
float oldDist = 0;
int width = 0;
int height = 0;
float fitScaleX = 1.0f;
float fitScaleY = 1.0f;
static final int STATE_NONE = 0;
static final int STATE_DRAG = 1;
static final int STATE_ZOOM = 2;
int mode = STATE_NONE;
long doubleClickStartTime = 0;
boolean doubleClickFlag = false;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.chart);
view = (ImageView) findViewById(R.id.imageViewChart);
view.setOnTouchListener(this);
getFitScale();
matrix.postScale(fitScaleX, fitScaleY, 0, 0);
view.setImageMatrix(matrix);
}
public void onStart() {
super.onStart();
}
private void getFitScale() {
Resources rs = getResources();
Drawable dw = rs.getDrawable(R.drawable.chart);
width = dw.getIntrinsicWidth();
height = dw.getIntrinsicHeight();
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
fitScaleX = (float)dm.widthPixels/(float)width;
fitScaleY = fitScaleX;
}
public boolean onTouch(View v, MotionEvent event)
{
// Handle touch events here...
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
savedMatrix.set(matrix);
start.set(event.getX(), event.getY());
mode = STATE_DRAG;
break;
case MotionEvent.ACTION_UP:
mode = STATE_NONE;
// for Auto Fitting
if(doubleClickFlag == false)
doubleClickStartTime = SystemClock.uptimeMillis();
if(doubleClickFlag) {
if(SystemClock.uptimeMillis() - doubleClickStartTime < 500) {
matrix.reset();
matrix.postScale(fitScaleX, fitScaleY, 0, 0);
} else {
doubleClickStartTime = SystemClock.uptimeMillis();
doubleClickFlag = false;
}
}
if(doubleClickFlag == false)
doubleClickFlag = true;
else
doubleClickFlag = false;
break;
case MotionEvent.ACTION_POINTER_UP:
mode = STATE_NONE;
break;
case MotionEvent.ACTION_MOVE:
if (mode == STATE_DRAG) {
float dx = event.getX() - start.x;
float dy = event.getY() - start.y;
float[] values = new float[9];
matrix.set(savedMatrix);
matrix.getValues(values);
if(values[Matrix.MTRANS_X]+ dx < view.getWidth() - width * values[Matrix.MSCALE_X]) {
dx = view.getWidth() - values[Matrix.MTRANS_X] - width * values[Matrix.MSCALE_X];
}
else if(values[Matrix.MTRANS_X]+ dx > 0) {
dx = 0 - values[Matrix.MTRANS_X];
}
if(values[Matrix.MTRANS_Y] + dy < view.getHeight() - height*values[Matrix.MSCALE_Y]) {
dy = view.getHeight() - height * values[Matrix.MSCALE_Y] - values[Matrix.MTRANS_Y];
}
else if(values[Matrix.MTRANS_Y] + dy > 0) {
dy = 0 - values[Matrix.MTRANS_Y];
}
matrix.postTranslate(dx, dy);
}
else if (mode == STATE_ZOOM) {
float newDist = spacing(event);
matrix.set(savedMatrix);
if (newDist > 10f) {
float[] values = new float[9];
matrix.set(savedMatrix);
matrix.getValues(values);
float scale = newDist/oldDist;
if(values[Matrix.MSCALE_X] * scale > 3.0f ||
values[Matrix.MSCALE_Y] * scale > 3.0f ) {
matrix.reset();
matrix.postScale(3.0f, 3.0f, 0, 0);
}
else if(values[Matrix.MSCALE_X] * scale < fitScaleX ||
values[Matrix.MSCALE_Y] * scale < fitScaleY) {
matrix.reset();
matrix.postScale(fitScaleX, fitScaleY, 0, 0);
}
else {
matrix.postScale(scale, scale, 0, 0);
}
}
}
break;
case MotionEvent.ACTION_POINTER_DOWN:
oldDist = spacing(event);
if (oldDist > 10f) {
savedMatrix.set(matrix);
midPoint(mid, event);
mode = STATE_ZOOM;
}
break;
}
// Perform the transformation
view.setImageMatrix(matrix);
return true; // indicate event was handled
}
private float spacing(MotionEvent event) {
float x = event.getX(0) - event.getX(1);
float y = event.getY(0) - event.getY(1);
return FloatMath.sqrt(x * x + y * y);
}
private void midPoint(PointF point, MotionEvent event) {
float x = event.getX(0) + event.getX(1);
float y = event.getY(0) + event.getY(1);
point.set(x/2, y/2);
}
}
結果を、単にそれにリンクするのではなく要約してください。 – McKay
要約ポイントの1つは、gcがガベージコレクションを頻繁に行うことを可能にする、最後にビットマップ参照をnullに設定することです。これにはいくつかの回避策がありますので、そのリンクを参考にしてください。 – kosa
申し訳ありませんが、私はコードを変更する必要があります理解できません。ご指定ください。 – user1129820