我目前正在开发一款 Android 游戏,并遇到了有关 Activity 和 Renderer 之间通信的问题。
场景
我有一个 Activity
,其中 GLSurfaceView
作为内容 View ,并且有一个附加到 GLSurfaceView
的 Renderer
。 Renderer
包含游戏循环。它绘制场景并更新游戏状态。这似乎是最佳实践,并且到目前为止运行顺利。 Activity
还显示 UI 元素,例如按钮或游戏得分。
Activity
在 UI 线程中运行,Renderer
有自己的线程。所以基本上我必须处理线程间通信。我使用 GLSurfaceView.queueEvent(Runnable) 来从 Activity 调用 Renderer 线程中的某些内容(例如启动游戏循环)。要从 Renderer
调用 UI 线程中的某些内容(例如更新游戏分数 UI 元素),我使用 Activity.runOnUiThread(Runnable)
。
问题
每次我想与其他线程通信时,都必须实例化一个Runnable
。在某些时候,这将触发垃圾收集,因为虚拟机需要释放内存。这当然会中断游戏。
问题
是否有无需实例化新对象的替代方案?目标是在游戏运行时保持内存分配恒定。
最佳答案
不要为每条消息分配 Runnables。为接收消息的线程创建一个处理程序,并使用例如获取消息对象obtainMessage()
以避免分配。
您可以在 Grafika 中找到多个这样的示例,它采取措施尽量减少或消除各种 Activity 的分配。 Android Breakout在游戏过程中没有[*]分配(尽管它在玩游戏时不使用任何 View UI)。
建议切换到 native 代码通常是多余的,特别是如果您的唯一目的是避免垃圾收集。
评估游戏状态的最佳工具是 DDMS allocation tracker ,显示 N 个最近的分配。
[*] 我已经有一段时间没有查看 Android Breakout 了。目标是零分配。
关于Android:Activity 和 Renderer 之间的内存优化通信 (GLSurfaceView),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34292665/