android - 位图复制自己,直到 android 应用程序崩溃

标签 android bitmap surfaceview

所以我得到了一个应用程序,它应该将 2 个位图放在相机预览之上。但是,位图会 self 复制直到崩溃,因为我切换到表面 View 而不是 View 以允许相机预览到位。谁能帮忙?

CameraActivity.java:

package com.cs461.Ian;

//TODO:Add accelerometer support
//TODO:Add Clickable ghosts
//TODO:Add camera background
/*Completed:(As of 2:30am 4/16)
 * Activity launches
 * Ghost appears on screen
 * Ghost will randomly move around the screen
 */

import java.io.IOException;
import java.util.Random;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.hardware.Camera;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

public class CameraActivity extends Activity{

Bitmap g;
Ghost a;
Ghost still;
SurfaceHolder mSurfaceHolder;
boolean firsttime=true;
int draw_x,draw_y,xSpeed,ySpeed;
static int score=0;
static TextView t;
static Camera bgCamera;

@Override
public boolean dispatchTouchEvent(MotionEvent event){
    return false;

}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //setContentView(R.layout.game);
    a = new Ghost(getApplicationContext());
    still = new Ghost(getApplicationContext());

    a.Initalize(BitmapFactory.decodeResource(getResources(), R.drawable.ghost), 120, 120);
    still.Initalize(BitmapFactory.decodeResource(getResources(), R.drawable.ghost), 120, 120);



    /*a.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if (event.getAction() == MotionEvent.ACTION_DOWN){
                score++;
                t.setText("Score: "+score);
                Log.w("CLICKED","Clicked on ghost "+score+" times");

            }
            return true;
        }
    });
    Log.w("Added","Still added ontouchlistener");
    still.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if (event.getAction() == MotionEvent.ACTION_DOWN){
                score++;
                t.setText("Score: "+score);
                Log.w("CLICKED","Clicked on ghost "+score+" times");

            }
            return true;
        }
    });*/



    setContentView(new Panel(this));
}

class DrawThread extends Thread {
    private SurfaceHolder _surfaceHolder;
    private Panel _panel;
    private boolean _run = false;

    public DrawThread(SurfaceHolder surfaceHolder, Panel panel) {
        _surfaceHolder = surfaceHolder;
        _panel = panel;
    }

    public void setRunning(boolean run) {
        _run = run;
    }

    @Override
    public void run() {

        runOnUiThread(new Runnable() {
             public void run() {
                 Canvas c;

        //stuff that updates ui             

        while(_run) {
            c = null;
            try {
                c = _surfaceHolder.lockCanvas(null);
                synchronized(_surfaceHolder) {
                    _panel.invalidate();
                    _panel.onDraw(c);
                }
            } finally {
                if (c != null) {
                    _surfaceHolder.unlockCanvasAndPost(c);
                }
            }

        }
             }
        });
    }
}

class Panel extends SurfaceView implements SurfaceHolder.Callback {
    private DrawThread _thread;

    public Panel(Context context) {
        super(context);
        getHolder().addCallback(this);
        _thread = new DrawThread(getHolder(), this);
    }

    @Override
    public void onDraw(Canvas canvas) {
        //g.Initalise(BitmapFactory.decodeFile("/res/drawable-hdpi/ghost.png"), 200, 150, 5, 5);;
        update(canvas);
        invalidate();
    }

    /*Places ghost on screen and bounces it around in the screen. My phone is apparently only API level 4(the most up to date is 15) so i didn't code it
     *for the accelerometer yet.
     */
    public void update(Canvas canvas) {
        Random rand = new Random();

        if(firsttime){
            draw_x = Math.round(System.currentTimeMillis() % (this.getWidth()*2)) ;
            draw_y = Math.round(System.currentTimeMillis() % (this.getHeight()*2)) ;
            xSpeed = rand.nextInt(10);
            ySpeed = rand.nextInt(10);
            still.draw(canvas);
            firsttime=false;
        }
         draw_x+=xSpeed;
         draw_y+=ySpeed;
         draw_x = Math.round(System.currentTimeMillis() % (this.getWidth()*2)) ;
         draw_y = Math.round(System.currentTimeMillis() % (this.getHeight()*2)) ;
         if (draw_x>this.getWidth()){
          draw_x = (this.getWidth()*2)-draw_x;
          xSpeed = rand.nextInt(10);
          if(xSpeed >=5)
              xSpeed=-xSpeed;
         }
         if (draw_y>this.getHeight()){
          draw_y = (this.getHeight()*2)-draw_y;
          ySpeed = rand.nextInt(10);
          if(ySpeed >=5)
              ySpeed=-ySpeed;
         }

         //g = BitmapFactory.decodeResource(getResources(), R.drawable.ghost);
         //canvas.drawBitmap(g, 0, 0, null);

         a.update(canvas);



    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {
        // TODO Auto-generated method stub
        invalidate();
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        _thread.setRunning(true);
        _thread.start();

        new Cam().execute(getApplicationContext());
         //try {
            //bgCamera.setPreviewDisplay(getHolder());
        //} catch (IOException e) {
            // TODO Auto-generated catch block
        //  e.printStackTrace();
        //}
       // bgCamera.startPreview();

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
         boolean retry = true;
            _thread.setRunning(false);
            while (retry) {
                try {
                    _thread.join();
                    invalidate();
                    retry = false;
                } catch (InterruptedException e) {
                    // we will try it again and again...
                }
            }

    }


}



}

幽灵.java:

package com.cs461.Ian;

import java.util.Random;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

public class Ghost extends View implements View.OnTouchListener{
public Ghost(Context context) {
    super(context);
    // TODO Auto-generated constructor stub
}

private Bitmap mAnimation;
private int mXPos;
private int mYPos;
private Rect mSRectangle;
private int mSpriteHeight;
private int mSpriteWidth;
View v;
Rect dest;
int score = 0;

/*public Ghost() {
    mSRectangle = new Rect(0,0,0,0);
    mXPos = 80;
    mYPos = 200;
}*/



public void Initalize(Bitmap theBitmap, int Height, int Width) {
    mSRectangle = new Rect(0,0,0,0);
    mXPos = 80;
    mYPos = 200;
    mAnimation = theBitmap;
    mSpriteHeight = Height;
    mSpriteWidth = Width;
    mSRectangle.top = 0;
    mSRectangle.bottom = mSpriteHeight;
    mSRectangle.left = 0;
    mSRectangle.right = mSpriteWidth;
    dest = new Rect(mXPos, mYPos, mXPos + mSpriteWidth,
            mYPos + mSpriteHeight);

}
public void draw(Canvas canvas) {


    canvas.drawBitmap(mAnimation, mXPos, mYPos, null);
}

public void update(Canvas canvas) {
    new Random();
    canvas.translate(1, 1);
    mXPos = Math.round(System.currentTimeMillis() % (canvas.getWidth()*2)) ;
    mYPos = Math.round(System.currentTimeMillis() % (canvas.getHeight()*2)) ;
    if (mXPos>canvas.getWidth())
      mXPos = (canvas.getWidth()*2)-mXPos;
    if (mYPos>canvas.getHeight())
      mYPos = (canvas.getHeight()*2)-mYPos;

     draw(canvas);


}

public Rect getRect() {
    return mSRectangle;
}
@Override
public boolean onTouch(View v, MotionEvent event) {
    score++;
    //CameraActivity.t.setText("Score: "+CameraActivity.score);
    Log.w("CLICKED","Clicked on ghost "+score+" times");
    return true; //doesn't work if returns false either
}


}

最佳答案

尝试在每次重绘时释放位图资源。如果 a 是您的位图,请调用 a.release()

关于android - 位图复制自己,直到 android 应用程序崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10387137/

相关文章:

java - 自定义 ListView 适配器抛出 UnsupportedOperationException

android - 检测颜色的圆圈会在OpenCV中产生 “image must be 8-bit single-channel in HoughCircle”错误

java - Android:共享位图未保存到 SD

android - 如何通过编程方式使用apk获取开发的组织名称?

android - android 中的 gcm 注册失败

java.lang.OutOfMemoryError : Android 错误

android - 在 CameraPreview 上使用 ViewPager

android - 如何拍摄surfaceview的快照?

android - 如何在 Android 中平滑地实现放大缩小?与带有 RTMP 流的 SurfaceView 相关

java - 当我将默认的 xml 布局文件更改为另一个时,Android 应用程序崩溃