高效的android渲染

时间:2011-07-01 15:04:10

标签: android drawing cpu-usage

我在android上阅读了很多有关游戏编程的教程, 并且它们都提供了与绘制游戏基本相同的解决方案,即具有如此旋转的专用线程:

public void run() { 
    while(true) { 
        if(!surfaceHolder.getSurface().isValid()) continue; 
        Canvas canvas = surfaceHolder.lockCanvas(); 
        drawGame(canvas); /* do actual drawing here */
        surfaceHolder.unlockCanvasAndPost(canvas); 
    }
} 

现在我想知道,这不是浪费吗?假设我的游戏图形非常简单,那么drawGame中的实际时间很少; 然后我将继续绘制相同的东西,从其他线程中窃取cpu; 如果游戏状态没有改变,可能会跳过绘图并稍微睡一觉, 我可以通过让状态更新线程保持合适的状态标志来检查。 但也许还有其他选择。例如,无法与渲染同步, 所以我不经常发布更新?或者我错过了什么,这正是lockCanvas所做的, 那是在适当的时候阻止并烧掉没有cpu吗?

提前致谢

L,

2 个答案:

答案 0 :(得分:1)

我会说你看过的教程是错误的,你真的想在主循环中等待。在下面的示例中,16毫秒将是目标帧时间

public void run() { 
    while(true) { 
        long start = System.currentTimeMillis();
        if(!surfaceHolder.getSurface().isValid()) continue; 
        Canvas canvas = surfaceHolder.lockCanvas(); 
        drawGame(canvas); /* do actual drawing here */
        surfaceHolder.unlockCanvasAndPost(canvas); 
        long frameTime =  System.currentTimeMillis() - start;
        try {
            Thread.sleep(Math.max(0, 16 - ( frameTime )));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
} 

答案 1 :(得分:0)

您不需要从线程中的循环中绘制画布,您可以根据请求执行此操作,就像在屏幕上移动手指一样。

如果动画不是密集的,可以只使用自定义视图,然后从某个用户输入事件中使视图无效(

)。

也可以在相同的SurfaceView类中停止线程,然后再次创建并重新启动它。