2010-05-07 49 views
0

只是想开始说这看起来像一个伟大的网站,希望你们可以帮忙!我该如何解决这个触摸事件/绘制循环“死锁”?

我试图使用LunarLander中布局的结构来创建一个简单的游戏,用户可以在屏幕上拖动一些位图(实际的游戏更复杂,但并不重要)。我撕掉了LanderLander的不相关部分,并成立了自己的位图绘制,像

BoardThread (an inner class of BoardView): 
run() 
{ 
    while(mRun) 
    { 
    canvas = lockSurfaceHolder... 
    syncronized(mSurfaceHolder) 
    { 
     /* drawStuff using member position fields 
     in BoardView */ 
    } 
    unlockSurfaceHolder 
    } 
} 

我drawStuff只是通过一些列散步,抛出位图到画布上。所有的工作正常。然后,我想要开始处理触摸事件,以便在用户按下位图时选择该位图,当用户取消位图时取消选择该位图,并且如果在触摸移动事件中选择位图,则位图将被拖动。我通过在BoardView的父级BoardActivity中侦听触摸事件并将它们传递到BoardView中来完成这件事。类似于

In BoardView 
handleTouchEvent(MotionEvent e) 
{ 
    synchronized(mSurfaceHolder) 
    { 
    /* Modify shared member fields in BoardView 
     so BoardThread can render the bitmaps */ 
    } 
} 

这也适用。我可以在屏幕上拖动我的瓷砖没问题。

但是,每当偶尔首次启动应用程序并触发我的第一个触摸事件时,handleTouchEvent将停止在同步行处执行(如在DDMS中所看到的那样)。绘图循环在这段时间内处于活动状态(我可以告诉,因为计时器会在屏幕上变化),并且通常需要几秒钟或更长时间才能通过管道传输一堆触摸事件,并且一切都很顺利。

对我来说,这看起来并不像死锁,因为绘制循环会不停地进出同步块。不应该让事件处理线程在mSurfaceHolder上获取锁吗?这里发生了什么?任何人都有改善我这种结构的建议吗?

其他信息。这种“挂起”只发生在活动开始后的第一次触摸事件上。这包括调用restoreState后的方向更改。另外,我可以在事件处理程序的syncronized块中删除EVERYTHING,并且它仍然会挂起同步化的呼叫。

谢谢!

回答

0

So Rob Green rbgrn帮助我了解了更多信息。我最终使用了一个并发队列来将触摸事件传递给我的游戏线程,但是当saveInstanceState被调用时,我仍然有问题,所以我现在在我的游戏线程的每个迭代的底部调用Thread.sleep(16)循环。充分讨论here