如何修复此触摸事件/绘制循环“死锁”?

时间:2010-05-07 17:22:03

标签: android synchronization

只想说这看起来像一个很棒的网站,希望你们能帮忙!

我正在尝试使用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 */
  }
}

这个ALSO工作正常。我可以在屏幕上拖动我的瓷砖没问题。

然而,每隔一段时间,当应用程序首次启动并触发我的第一个触摸事件时,handleTouchEvent将停止在同步行中执行(在DDMS中查看)。绘图循环在此期间处于活动状态(我可以判断,因为计时器在屏幕上发生了变化),通常需要几秒钟或更长时间才能通过管道进行一系列触摸事件,一切都很好。

这对我来说似乎不是死锁,因为绘制循环不断地进出同步块。这不应该允许事件处理线程获取mSurfaceHolder上的锁吗?这里发生了什么?有人建议改进我的结构吗?

其他一些信息。这种“挂起”仅在活动开始后的第一次触摸事件中发生。这包括调用restoreState后的方向更改。此外,我可以在事件处理程序中的同步块中删除所有内容,并且它仍会在同步调用中挂起。

谢谢!

1 个答案:

答案 0 :(得分:0)

来自rbgrn的Rob Green帮助我获得了更多信息。我最终使用并发队列将触摸事件传递给我的游戏线程,但是当调用saveInstanceState时我仍然遇到悬挂问题,所以我现在在我的游戏线程的每次迭代的底部调用Thread.sleep(16)环。完整的讨论here