2012-01-04 53 views
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); 
} 
} 

回答

1

位图图像消耗大量的内存,这是更好地降低它们的分辨率。以下是与此问题的几个解决方法的链接。 Bitmap images exceed VM budget work arounds

+0

请总结一下结果,而不仅仅是链接到它? – McKay 2012-01-04 16:58:42

+0

其中一个总结点是在最后将你的位图引用设置为null,这将允许gc频繁地进行垃圾回收。对此有几个解决方法,所以引用该链接可能会有所帮助。 – kosa 2012-01-04 17:03:32

+0

对不起,无法理解我必须在哪里更改代码。请明确说明。 – user1129820 2012-01-04 18:49:47

相关问题