1

在我的应用程序中,我需要在画布中显示图像,我尝试使用下面的代码,它的工作效果很好。但如果一次又一次地播放同一页面,我的位图大小超出内存异常。我在网上冲浪,我当时设置了样本大小我也遇到了例外,请任何人帮助我这么多天在病房里遇到这个问题。

  Lines.class 

 public class Lines extends Activity
   {

  BitmapDrawable  sounddrawable,erasedrawable,backdrwable,fwddrwable,captiondrwable,img1drwable;
Bitmap img1bitmap,soundbitmap,eraseBitmap,backbitmap,fwdbitmap,captionbitmap;
Bitmap bitmapOrg1,bitmapOrg2,bitmapOrg3,bitmapOrg4,bitmapOrg5,bitmapOrg6,bitmapOrg;

MyView myview;
   View content;
 float screenHeight,screenWidth,screendensity;
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setNoTitle();
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

    DisplayMetrics displaymetrics = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
     screenHeight = displaymetrics.heightPixels;
     screenWidth = displaymetrics.widthPixels;
     screendensity = displaymetrics.densityDpi;
    Log.i("screenHeight",""+screenHeight);
    Log.i("screenWidth",""+screenWidth);
    Log.i("screendensity",""+screendensity);

         setContentView(R.layout.line);

         widtho=(int)(91*(screenWidth/1024));
     highto=(int)(175*(screenHeight/600));
    bitmapOrg = Bitmap.createScaledBitmap(bitmapOrg, widtho, highto, true);
    leftorg=(int)(120*(screenWidth/1024));
    toporg=(int)(130*(screenHeight/600));


      bitmapOrg1 = BitmapFactory.decodeResource(getResources(),
                R.drawable.line1_2);

       width1=(int)(90*(screenWidth/1024));
        hight1=(int)(175*(screenHeight/600));
        bitmapOrg1 = Bitmap.createScaledBitmap(bitmapOrg1, width1, hight1, true);
      leftorg1=(int)(300*(screenWidth/1024));
       toporg1=(int)(130*(screenHeight/600));


  bitmapOrg2 = BitmapFactory.decodeResource(getResources(),
                R.drawable.line1_3);


    bitmapOrg2 = Bitmap.createScaledBitmap(bitmapOrg2, widtho, highto, true);

  leftorg2=(int)(470*(screenWidth/1024));
   toporg2=(int)(130*(screenHeight/600));


           bitmapOrg3 = BitmapFactory.decodeResource(getResources(),
                R.drawable.line1_4);
   bitmapOrg3 = Bitmap.createScaledBitmap(bitmapOrg3, width1, hight1, true);
              leftorg3=(int)(640*(screenWidth/1024));
  toporg3=(int)(130*(screenHeight/600));


          bitmapOrg4 = BitmapFactory.decodeResource(getResources(),
                R.drawable.line1_5);




          bitmapOrg4 = Bitmap.createScaledBitmap(bitmapOrg4, width1, hight1, true);
              leftorg4=(int)(810*(screenWidth/1024));
      toporg4=(int)(130*(screenHeight/600));



     bitmapOrg5 = BitmapFactory.decodeResource(getResources(),
                R.drawable.line1_6);


      width6=(int)(237*(screenWidth/1024));
       hight6=(int)(139*(screenHeight/600));
            bitmapOrg5 = Bitmap.createScaledBitmap(bitmapOrg5, width6, hight6, true);
leftorg5=(int)(150*(screenWidth/1024));
           toporg5=(int)(370*(screenHeight/600));


         bitmapOrg6 = BitmapFactory.decodeResource(getResources(),
                R.drawable.line1_7);

             bitmapOrg6 = Bitmap.createScaledBitmap(bitmapOrg6, width6, hight6, true);
        leftorg6=(int)(600*(screenWidth/1024));
          toporg6=(int)(370*(screenHeight/600));

  }   
       mPaint = new Paint();

    mPaint.setAntiAlias(true);
    mPaint.setDither(true);

    mPaint.setColor(Color.BLACK);
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setStrokeJoin(Paint.Join.ROUND);
    mPaint.setStrokeCap(Paint.Cap.ROUND);
    mPaint.setStrokeWidth(6);

    }

     private void setNoTitle() {
    // TODO Auto-generated method stub
    requestWindowFeature(Window.FEATURE_NO_TITLE);
}
 private Paint       mPaint;
  private Bitmap  mBitmap;

    public void colorChanged(int color) {
        mPaint.setColor(color);
    }

    public class MyView extends View
    {

            private Canvas  mCanvas;
            private Path    mPath;
            private Paint   mBitmapPaint;

        public MyView(Context context) {
            super(context);
            // TODO Auto-generated constructor stub

             mPath = new Path();



                mBitmapPaint = new Paint(Paint.DITHER_FLAG);

        }
         @Override
            protected void onSizeChanged(int w, int h, int oldw, int oldh) {
                super.onSizeChanged(w, h, oldw, oldh);

                if (mBitmap != null) {
                    mBitmap.recycle();
                    mBitmap=null;
                 }

               mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);


                mCanvas = new Canvas(mBitmap);

                mCanvas.setBitmap(mBitmap);

            }

         @Override
            protected void onDraw(Canvas canvas) {

              if(action)
              {
                  invalidate();
              }


              Paint painto = new Paint();
               painto.setAntiAlias(true);
              painto.setColor(getResources().getColor(R.color.magnata));

               painto.setStrokeWidth(3);
               painto.setStyle(Paint.Style.FILL);


                      bitmapOrg.recycle();
               canvas.drawBitmap(bitmapOrg, leftorg, toporg, null);
               bitmapOrg1.recycle();
             canvas.drawBitmap(bitmapOrg1, leftorg1,toporg1, null);

              bitmapOrg2.recycle();

             canvas.drawBitmap(bitmapOrg2, leftorg2,toporg2, null);
             bitmapOrg3.recycle();
                canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
                canvas.drawBitmap(bitmapOrg3, leftorg3,toporg3, null);

                bitmapOrg4.recycle();
                canvas.drawBitmap(bitmapOrg4, leftorg4,toporg4, null);

                bitmapOrg6.recycle();

                canvas.drawBitmap(bitmapOrg6, leftorg6,toporg6, null);

                bitmapOrg5.recycle();
                canvas.drawBitmap(bitmapOrg5, leftorg5,toporg5, null);

               canvas.drawPath(mPath, mPaint);  
     } 
         private float mX, mY;
      private   float TOUCH_TOLERANCE = 2;
         private void touch_start(float x, float y) {
                 mPath.reset();
                  mPath.moveTo(x, y);
                      mX = x;
            mY = y;
              }
  private void touch_move(float x, float y) {
      float dx = Math.abs(x - mX);
      float dy = Math.abs(y - mY);
     if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
  mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2);
  mX = x;
  mY = y;
   }
   }
 private void touch_up() {
    mPath.lineTo(mX, mY);

   mCanvas.drawPath(mPath, mPaint);

    mPath.reset();
  }

@Override
         public boolean onTouchEvent(MotionEvent event) {
      float x = event.getX();
          float y = event.getY();

  switch (event.getAction()) {
      case MotionEvent.ACTION_DOWN:
      touch_start(x, y);
      invalidate();
      break;
  case MotionEvent.ACTION_MOVE:
      touch_move(x, y);
      invalidate();
      break;
  case MotionEvent.ACTION_UP:
      touch_up();
      invalidate();
      break;
      }
        return true;
}
 }
4

1 回答 1

-1

我不确定您为什么会收到 OutOfMemory 错误(因为您没有发布堆栈跟踪,我猜这不是您遇到的实际错误)。

您对 Bitmap.recycle() 的使用很可能是问题所在。它仅在您丢弃位图时使用,并且永远不会再次引用它。在任何情况下实际上都没有必要调用它,它只会导致对本机内存的早期清理,当 Bitmap 最终确定时将被释放。

文档说:

释放与此位图关联的本机对象,并清除对像素数据的引用。这不会同步释放像素数据;如果没有其他引用,它只是允许它被垃圾收集。该位图被标记为“死”,这意味着如果调用 getPixels() 或 setPixels() 将引发异常,并且不会绘制任何内容。此操作无法反转,因此只有在您确定位图没有进一步用途时才应调用它。这是一个高级调用,通常不需要调用,因为当没有更多对该位图的引用时,正常的 GC 进程将释放此内存。

因此,您绝对不应该在 onDraw 中调用它,而且绝对不能在尝试将位图绘制到画布之前调用它。我的建议是删除所有对 recycle() 的调用。

于 2013-02-27T07:03:44.283 回答