Android Canvas Thread变得疯狂

时间:2015-07-29 14:35:37

标签: java android multithreading canvas callback

嗨,大家好:)我正试着用我的Mainthreat画在画布上。 基本上我的目标是获得一个矩形,当我触摸它时它会改变颜色。 在onCreate方法中,我创建矩形并调用 quadr1.setColor 方法为其填充。然后我开始威胁。现在,绘制方法应该只回忆 quadr1.draw 方法,并重绘相同颜色的矩形。当我触摸quadr1时,威胁再次呼叫 quadr1.setColor ,而不是 quadr1.draw 。这应该为我的 RandomColor类提供一种新颜色(工作正常)。

现在的问题是:当威胁在运行时,画布就会消失,以显示"背后是什么?并重新开始下一步行动。它看起来像是癫痫症的折磨方法。我读到了关于双缓冲,但自己找不到任何解决方案。如何让它显示填充稳定的矩形,并在触摸时改变?

public class GamePanel extends SurfaceView implements SurfaceHolder.Callback{

    private MainThread thread;
    private Canvas canvas;
    private Random random;
    private SurfaceHolder holder;
    RandomColor randomColor = new RandomColor();
    private boolean colorChangeTouchInput;

    private Quadr quadr1;

    public GamePanel(Context context){
        super(context);

        SurfaceHolder holder = getHolder();
        holder.addCallback(this);
        this.holder = holder;

        thread = new MainThread(holder);
        randomColor = new RandomColor();

        setFocusable(true);
    }

    class MainThread extends Thread{
        private boolean running;
        private SurfaceHolder surfaceHolder;

        public MainThread(SurfaceHolder surfaceHolder){
            this.surfaceHolder = surfaceHolder;
        }

        @Override
        public void run(){
            while(running) {
                canvas = null;
                try {
                    canvas = surfaceHolder.lockCanvas();
                    synchronized (surfaceHolder) {
                        if(colorChangeTouchInput=false) {
                            draw(canvas);
                        } else {
                            quadr1.setColor(canvas);
                        }
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    if(canvas!= null){
                        surfaceHolder.unlockCanvasAndPost(canvas);
                    }
                }
            }
        }

        private void draw(Canvas canvas) {
            quadr1.draw(canvas);
        }
        public void setRunning(boolean b) {
            running = b;
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder){
        boolean retry = true;
        int counter =0;
        while(retry && counter <1000) {

            counter++;
            try {
                thread.setRunning(false);
                thread.join();
                retry=false;

            } catch(InterruptedException e){
                e.printStackTrace();
            }
        }
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder){


        WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
        Display display = wm.getDefaultDisplay();
        Point size = new Point();
        display.getSize(size);
        int windowWidth = size.x;
        int windowHeight = size.y;

        canvas = null;
        canvas = holder.lockCanvas();

        quadr1 = new Quadr(0,0,windowWidth/2,windowHeight / 2, randomColor.getRandomColorA(), randomColor.getRandomColorR(), randomColor.getRandomColorG(), randomColor.getRandomColorB());
        quadr1.setColor(canvas);

        holder.unlockCanvasAndPost(canvas);

        thread.setRunning(true);
        thread.start();
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        SurfaceHolder holderTouch = getHolder();

        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                if(event.getX()>quadr1.getLeft() && event.getX()<quadr1.getRight() && event.getY()>quadr1.getTop() && event.getY()<quadr1.getBot()){
                    colorChangeTouchInput = true;  
                }             
        }      
        return super.onTouchEvent(event);
    }

    public boolean isColorChangeTouchInput() {
        return colorChangeTouchInput;
    }
}

这是我的四级课程: (工作正常,也是随机颜色类,在几个方面测试它。)

public class Quadr extends GameObject {
    int left;
    int top;
    int right;
    int bot;
    int colorA[];
    int colorR[];
    int colorG[];
    int colorB[];
    int colorFixed;

    Paint paint = new Paint();
    Rect rect = new Rect();
    Random rnd = new Random();

    public Quadr(int left, int top, int right, int bottom, int colorA[], int colorR[], int colorG[], int colorB[]) {
        this.left=left;
        this.top=top;
        this.right=right;
        this.bot=bottom;
        this.colorA=colorA;
        this.colorR=colorR;
        this.colorG=colorG;
        this.colorB=colorB;

        rect.set(left, top, right, bottom);
    }

    public void setColor(Canvas canvas){
        int num = rnd.nextInt(3);
        colorFixed = num;

        paint.setStyle(Paint.Style.FILL);
    rnd.nextInt(256));
        paint.setARGB(colorA[num], colorR[num], colorG[num], colorB[num]);
        canvas.drawRect(rect, paint);
    }

    public void draw(Canvas canvas) {
        paint.setStyle(Paint.Style.FILL);
        paint.setARGB(colorA[colorFixed], colorR[colorFixed], colorG[colorFixed], colorB[colorFixed]);
        canvas.drawRect(rect, paint);

    }

    public int getLeft() {
        return left;
    }
    public int getTop() {
        return top;
    }
    public int getRight() {
        return right;
    }
    public int getBot() {
        return bot;
    }
}

非常感谢您提供任何帮助!!

1 个答案:

答案 0 :(得分:1)

据我所知,问题可能是由colorChangeTouchInput造成的。

您在拦截触摸时将其设置为true,然后再从未将其设置为false。这将导致永远不会在线程中调用draw()方法。我建议您在致电colorChangeTouchInput = false后添加quadr1.setColor(canvas);