11

试图在单个画布上每毫秒绘制一些东西。我的意思是只向画布添加细节,而不是每帧都重绘它。所以这段代码给了我三种不同的画布。第三,然后再第一。为什么?

public void run() {
    this.run = true;
    Canvas canvas = null;
    while (run) {
        try {
            canvas = this.surfaceHolder.lockCanvas();
            synchronized (this.surfaceHolder) {
                Thread.sleep(delay);
                draw(new Img(canvas, size));
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            if (canvas != null) {
            this.surfaceHolder.unlockCanvasAndPost(canvas);
            }
        }
        synchronized (this) {
            if (wait) {
                try {
                    wait();
                } catch (Exception e) {}
            }
        }
    }
}

如果它是 android 三重缓冲 - 如何关闭它,或者用它做些什么?安卓 4.2.1

4

2 回答 2

2

如果您想保留以前的绘制,您应该在屏幕外画布中绘制它们并将它们绘制到您从锁定画布获得的画布上。

puesd 代码来说明这个想法:

Bitmap offScreenBitmap = Bitmap.createBitmap(100,200,Bitmap.ARGB_8888);
Canvas offScreenCanvas = new Canvas(offScreenBitmap);

onScreenCanvas = this.surfaceHolder.lockCanvas();

//always draw to te offScreenCanvas
offScreenCanvas.drawXxxx

//copy the data to on-screen canvas you got from the lock
onScreenCanvas.drawBitmap(offScreenBitmap);

unlockAndPost(onScreenCanvas)

那应该可以完成您的任务。正确的?

然后,在引擎盖下的一些东西:

是的,android 视图(surface IS A 视图)有多个缓冲区:一个由应用程序用于绘制,一个由系统用于渲染,有时当应用程序无法及时完成绘制时还有第三个缓冲区。没有办法关闭它,你也不想。这就是您已经观察到的锁定时获得不同画布的原因。

于 2013-04-30T12:37:28.207 回答
1
  1. 我建议不要在 Runnable 实现(其中方法返回 void)中命名布尔字段“run”。即使问题没有从冲突中浮现出来,它也是令人困惑的。也许“运行”或其他东西(任何东西)会更有意义 - 更容易调试。

  2. 多线程时不要使用 Object.wait。它不会总是(通常不会)按照您的预期行事。

  3. 您很可能会获得 Canvas 成员的多个实例,因为某处(可能在 Android 框架中,或者可能在您的代码中......很难说),“new Canvas(args)”被调用,而您认为是您的只有 Canvas 实例在另一个线程上。虽然您只有一个引用,但可以创建多个实例。

  4. 除非您确定需要这样做,否则我不建议使用 synchronized(whatever)。

  5. 挂在那里。这个问题非常令人困惑——我在去年春天解决了这个问题,这并不容易或有趣。

希望以上任何内容在某种程度上有所帮助。

-布兰登

于 2013-01-19T03:29:22.917 回答