【发布时间】:2012-10-12 08:38:25
【问题描述】:
我使用SurfaceView来创建选框功能,但有时在SurfaceView中的绘图线程开始运行后,UI线程被阻塞,我对BACK或MENU按钮的触摸没有被调度,并且ANR 产生。这种情况时有发生。
我猜这是因为 SurfaceView 中的绘图开始太早(当然我确保绘图发生在surfaceCreated() 和surfaceDestroyed() 之间),我猜绘图线程应该在完全初始化后开始,也许与活动有关?
当我在实际使用SurfaceHolder.lockCanvas() 返回的Canvas 的代码前添加Thread.sleep(100) 开始绘制时,问题几乎消失了,仍然出现,但频率低。如果我在画布上实际绘制东西之前让绘图线程休眠足够长的时间,那么问题就不会再发生了。
看起来我应该在 something 完全初始化后开始绘制,但我不知道那是什么东西。
这个SurfaceView作为一个普通的View放在布局文件中,下面是在surface上绘制的代码。
public void run() {
try {
// this is extremely crucial, without this line, surfaceView.lockCanvas() may
// produce ANR from now and then. Looks like the reason is that we can not start
// drawing on the surface too early
Thread.sleep(100);
} catch (Exception e) {}
while (running) {
Canvas canvas = null;
try{
long ts = System.currentTimeMillis();
canvas = surfaceHolder.lockCanvas();
if (canvas != null) {
synchronized (surfaceHolder) {
doDraw(canvas);
}
ts = System.currentTimeMillis() - ts;
if (ts < delayInterval) {
Thread.sleep(delayInterval - ts);
}
}
} catch (InterruptedException e) {
// do nothing
} finally {
if (canvas != null)
surfaceHolder.unlockCanvasAndPost(canvas);
}
}
}
【问题讨论】:
-
您的代码中的
surfaceHolder对象还有其他同步吗?无论如何你应该在unlockCanvasAndPost之后调用Thread.sleep,而不是在lockCanvas和unlockCanvasAndPost之间。 -
哦,不!你是救世主!当我将
Thread.sleep放在unlockCanvasAndPost之后时,问题再也不会发生,现在我不需要在循环开始时睡觉。请张贴作为答案,我会接受!
标签: android surfaceview