为什么lockCanvas()会变慢?

时间:2011-05-16 07:11:40

标签: android surfaceview android-canvas

我正在实现一个SurfaceView子类,我运行一个单独的线程来绘制SurfaceHolders Canvas。 我在调用lockCanvas()之前和之后测量时间,我从大约70ms到100ms。 有没有人能指出我为什么会得到如此高的时间?  这里是代码的相关部分:

public class TestView extends SurfaceView implements SurfaceHolder.Callback {

....

boolean created;
public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {

   mThread = new DrawingThread(mHolder, true);
   mThread.onWindowResize(width, height);
   mThread.start();
}

public void surfaceCreated(SurfaceHolder holder) {

    created = true;
}

public void surfaceDestroyed(SurfaceHolder holder) {
    created = false;

}
class DrawingThread extends Thread {
public void run() {
while(created) {



            Canvas canvas = null;
            try {
                            long t0 = System.currentTimeMillis();
            canvas = holder.lockCanvas(null);
            long t1 = System.currentTimeMillis();
                            Log.i(TAG, "Timing: " + ( t1 - t0) );
            } finally {
                holder.unlockCanvasAndPost(canvas);
            }
}

3 个答案:

答案 0 :(得分:5)

每次更改曲面时都会创建一个线程。你应该在surfaceCreated开始你的线程并在surfaceDestroyed中杀死它。 surfaceChanged适用于表面尺寸变化的情况。

来自SurfaceView。surfaceCreated docs:

  

首次创建曲面后立即调用此方法。实现这个应该启动他们想要的任何渲染代码。请注意,只有一个线程可以绘制到Surface 中,因此如果正常渲染将在另一个线程中,则不应在此处绘制Surface。

多线程可能会让你受到限制。来自SurfaceHolder。lockCanvas docs:

  

如果在Surface未准备好时(Callback.surfaceCreated之前或Callback.surfaceDestroyed之后)重复调用此方法,您的调用将被限制以降低速率,以避免消耗CPU。 / p>

但是,我不相信这是唯一的问题。 surfaceChanged实际上被多次调用了吗?

答案 1 :(得分:2)

这与在android图形框架中实际实现lockCanvas的方式有关。

您可能已经知道lockCanvas将返回一个您将用于绘制的免费内存。通过 free ,表示此内存不用于合成而不用于显示。简而言之,在内部,SurfaceView由双缓冲区备份,一个用于绘图,一个用于合成/显示。这个双缓冲区由BufferQueque管理。 如果构图/显示比绘图慢,我们必须等到我们有可用的空闲缓冲区。

答案 2 :(得分:1)