Java Android画布更新问题

Java Android画布更新问题,java,android,android-canvas,Java,Android,Android Canvas,我只是不想让它工作。 我看到这个网络不仅仅是用于简单的代码更正帖子。 但我认为这符合其他人的利益,因为没有好的教程 所以我调用了画布,我可以在ondraw()方法中绘制画布,但是当我尝试从游戏循环中绘制时,它什么也不绘制。我甚至没有收到错误消息 应用程序: draw.java: public class draw extends View { Canvas ca; View v; Paint paint; int width; int height;

我只是不想让它工作。 我看到这个网络不仅仅是用于简单的代码更正帖子。 但我认为这符合其他人的利益,因为没有好的教程

所以我调用了画布,我可以在
ondraw()
方法中绘制画布,但是当我尝试从游戏循环中绘制时,它什么也不绘制。我甚至没有收到错误消息

应用程序:

draw.java:

public class draw extends View {
    Canvas ca;
    View v;
    Paint paint;

    int width;
    int height;

    static final int MAX_GAME_SPEED=33;
    static int fps; 
    boolean running=true;



    int pw=0,ph=0;





    public draw(Context context) {
            super(context);
        }  

            @Override
        protected void onDraw(Canvas c){
        super.onDraw(c);
        paint = new Paint(); //Paint paint = new Paint();
        paint.setStyle(Paint.Style.FILL);


        //get screen size
        WindowManager wm = (WindowManager) this.getContext().getSystemService(Context.WINDOW_SERVICE);
        Display display = wm.getDefaultDisplay();


        width = display.getWidth();  // deprecated
        height = display.getHeight();  // deprecated







            // make the entire canvas white
            paint.setColor(Color.WHITE);
            c.drawPaint(paint);


            ca = c;
            paint.setColor(Color.BLACK);
            c.drawRect(Math.round(width/3),Math.round(height/3),Math.round((width/3)*2),Math.round((height/3)*2), paint); //position width, position height,width,height


            paint.setStyle(Paint.Style.FILL);
            paint.setAntiAlias(true);
            paint.setTextSize(30);
            paint.setColor(Color.GREEN);
            c.drawText(String.valueOf(width)+"x"+String.valueOf(height)+","+Math.round(width/3)+"x"+Math.round(height/3), 30, 200, paint);
            paint.setColor(Color.GREEN);
            c.drawText(String.valueOf(width)+"x"+String.valueOf(height)+","+Math.round(width/3)+"x"+Math.round(height/3), 30, 200, paint);


            Thread myThread = new Thread(new UpdateThread());
            myThread.start();

    }
            public void paint(Canvas c)
            {

                paint.setColor(Color.GREEN);
                c.drawRect(20, 5, 50, 100, paint);

                pw++;
                ph++;



                /*if (pw >= width || ph >= height)
                {
                    pw=0;
                    ph=0;
                }
                */

            }
            public Handler updateHandler = new Handler(){
                /** Gets called on every message that is received */
                // @Override
                public void handleMessage(Message msg) {

                   paint(ca);


                    super.handleMessage(msg);
                }
            };



            public class UpdateThread implements Runnable {

                @Override
                public void run() {
                     while(true){
                         draw.this.updateHandler.sendEmptyMessage(0);

                    }
                }

            }

    }

那么,您有一个视图,并且在onDraw()中创建了一个执行绘图的线程?为什么?您应该在UI线程上完成所有绘图,并将游戏的其他部分转移到其他线程。

您不需要额外的线程

只需使onDraw中的最后一条语句无效,onDraw将再次调度。

首先: 您发送更新消息的频率太高。我相信你的消息队列已经超载了

第二: 您正在使用onDraw方法保存的画布实例。我认为这是不对的。 相反,您可以将UpdateThread.run()方法更改为

@Override
public void run() {
    while(true){
        draw.this.postInvalidate();
    }
}
这将发送消息,使视图无效并重新绘制,从而使用正确的画布调用View.onDraw(Canvas)方法

此外: 如果要尽可能多地渲染视图,则必须实现下一个序列:

static final int MSG_REDRAW = 1;

Handler handler = new Handler() {
    public void handleMessage(Message msg) {
        switch (msg.what) {
        case MSG_REDRAW:
            // This method invoked on UI thread - ok.
            draw.this.invalidate();
            sendEmptyMessage(MSG_REDRAW);
            break;

        default:
            super.handleMessage(msg);
            break;
        }
    }
}

您只需发送第一条MSG_REDRAW消息,而不是调度线程(UpdateThread)。

我在postInvalidate和线程方面遇到一些问题。 首先尝试添加
setWillNotDraw(false)
当屏幕改变方向时,我遇到了一个问题——postInvalidate()重新绘制花了很多时间,因为调用了这个函数,我们不知道什么时候会调用onDraw,但它确实会被调用。

关于我的解决方案和问题,请看这个。

我正在使用旧的java教程构建此教程,我曾经为java手机制作过相同的gmae,但您的意思是如何做到这一点?如果您正在做类似于游戏的事情,您真的应该使用SurfaceView,因为它可以提供更好的速度。下面是一个关于如何做到这一点的教程:
static final int MSG_REDRAW = 1;

Handler handler = new Handler() {
    public void handleMessage(Message msg) {
        switch (msg.what) {
        case MSG_REDRAW:
            // This method invoked on UI thread - ok.
            draw.this.invalidate();
            sendEmptyMessage(MSG_REDRAW);
            break;

        default:
            super.handleMessage(msg);
            break;
        }
    }
}