2
我已经尝试开发一个应用程序。这对于一个小的101KB图像文件来说是可以的,但是当我使用这个应用程序而不是这个图像时,它将不会运行并显示:java.lang.OutOfMemoryError:位图大小超过虚拟机预算。如何避免内存泄露称为java.lang.OutOfMemoryError:位图大小超过虚拟机的预算Android
以下是我的代码:
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 2012-01-04 16:58:42
其中一个总结点是在最后将你的位图引用设置为null,这将允许gc频繁地进行垃圾回收。对此有几个解决方法,所以引用该链接可能会有所帮助。 – kosa 2012-01-04 17:03:32
对不起,无法理解我必须在哪里更改代码。请明确说明。 – user1129820 2012-01-04 18:49:47