【问题标题】:onSurfaceChanged called twiceonSurfaceChanged 调用了两次
【发布时间】:2015-05-04 15:46:41
【问题描述】:

我正在使用 openGL ES 创建一个 Android 应用程序,但遇到以下问题:

当我最小化应用程序,然后重新打开它时,我的 GLSurfaceView.Renderer 中的 onSurfaceChanged 被调用了 2 次。

我在 onSurfaceChanged 中有以下代码(以及 onSurfaceCreated,onDrawFrame 中的类似代码):

Log.e("onSurfaceChanged",Integer.toString(width)+" "+Integer.toString(height));

所以我得到以下日志:

onSurfaceCreated onSurfaceChanged 480 800 onDrawFrame onSurfaceChanged 480 800 onDrawFrame onDrawFrame onDrawFrame onDrawFrame onDrawFrame onDrawFrame (...)

当我最小化时,将屏幕方向从纵向更改为横向,然后重新打开,onSurfaceChanged 被调用 3 次。日志是:

onSurfaceCreated onSurfaceChanged 480 800 onDrawFrame onSurfaceChanged 480 800 onDrawFrame onDrawFrame onDrawFrame onSurfaceChanged 800 480 onDrawFrame onDrawFrame onDrawFrame onDrawFrame onDrawFrame onDrawFrame (...)

我的问题:这是一个错误吗?在我的应用程序中还是 Android 错误?有一种方法可以只调用一次 onSurfaceChanged 吗? (因为在 onSurfaceCreated 我正在执行减慢应用程序的代码)

提前致谢

【问题讨论】:

标签: android opengl-es-2.0 screen-orientation


【解决方案1】:

这不是错误。 就我个人而言,我在继承自 GLSurfaceView 的类中对 onSurfaceChanged 做的不多。 我只根据新的分辨率设置视口,并将当前的分辨率尺寸保存到变量中。

不需要在 onSurfaceChanged 处重新创建纹理等 OpenGL 资产,而是在 ActivityCycle 上选择正确的位置来创建和销毁您的 OpenGL 资产。

我正在多个平台上运行我的游戏,例如 Android、Amazon Fire TV 和 OUYA。我发现适用于所有这些平台的是在 onPause、onStop 和 onRestart 上销毁 GL 资产,但我还保留一个标志以查看资产是否已被销毁,因此我不会直接销毁它两次。

我在 onCreate、onRestart 和 onResume 处创建了 OpenGL 资产(也使用一个标志来不创建两次)。 如果您不希望游戏在暂停时丢失其状态,则必须序列化游戏状态并将其写入文件并稍后在您恢复时加载。

希望这会有所帮助。

同样,您无法真正预测您将收到多少 onSurfaceCreated,尤其是它在不同设备上的行为可能不同。 但是,您始终可以相信 ActivityCycle 会按照 Google 的描述行事。

【讨论】:

  • 旋转手机时,似乎调用了 onPause 并进行了垃圾收集。启动应用(垂直)``` * onCreate * onResume * onSurfaceCreated * onSurfaceChanged ``` 旋转(水平) ``` * onPause (garbageCollect) * onCreate * onResume * onSurfaceCreated * onSurfaceChanged ```
猜你喜欢
  • 2017-06-25
  • 2013-01-21
  • 2012-09-08
  • 2016-04-27
  • 2019-02-27
  • 1970-01-01
  • 2019-12-04
  • 2018-09-15
  • 2012-10-10
相关资源
最近更新 更多