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

答えて

1

、彼らの解像度を下げることをお勧めします。ここでは、この問題の回避策をいくつか挙げています。 Bitmap images exceed VM budget work arounds

+0

結果を、単にそれにリンクするのではなく要約してください。 – McKay

+0

要約ポイントの1つは、gcがガベージコレクションを頻繁に行うことを可能にする、最後にビットマップ参照をnullに設定することです。これにはいくつかの回避策がありますので、そのリンクを参考にしてください。 – kosa

+0

申し訳ありませんが、私はコードを変更する必要があります理解できません。ご指定ください。 – user1129820

関連する問題