我正在使用具有以下 calssic run() 方法的线程在 SurfaceView 上绘图:
@Override
public void run() {
while (mRun) {
Canvas canvas = null;
synchronized (mSurfaceHolder) {
try {
canvas = mSurfaceHolder.lockCanvas();
update();
doDraw(canvas);
} finally {
if (canvas != null) {
mSurfaceHolder.unlockCanvasAndPost(canvas);
}
}
}
}
}
如果从那一刻起即将绘制的下一帧与前一帧完全相同,我想节省一些工作,所以我跳过了 onDraw,但由于双缓冲机制,我遇到了闪烁问题。然后我继续做这样的事情:
@Override
public void run() {
while (mRun) {
Canvas canvas = null;
synchronized (mSurfaceHolder) {
if (mIsAnimating) { // <---- Look ma! A flag!!!
try {
canvas = mSurfaceHolder.lockCanvas();
update();
doDraw(canvas);
} finally {
if (canvas != null) {
mSurfaceHolder.unlockCanvasAndPost(canvas);
}
}
}
}
}
}
如果我关闭 mIsAnimating 标志,从而阻止我的运行循环锁定画布并在其上绘图,一切都像魅力一样工作 - 我做了一些动画,完成后,我可以冻结绘图周期并保留动画的最后一帧在屏幕上。
但后来我不得不去看看Android 文档中的以下内容:
在 unlockCanvas() 和 lockCanvas() 之间永远不会保留 Surface 的内容,因此,必须写入 Surface 区域内的每个像素。此规则的唯一例外是指定脏矩形时,在这种情况下,将保留非脏像素。
那么......我的代码是怎么工作的?