Android:使用 SurfaceView 重新获得焦点
Posted
技术标签:
【中文标题】Android:使用 SurfaceView 重新获得焦点【英文标题】:Android: Regaining focus using SurfaceView 【发布时间】:2010-10-14 21:54:25 【问题描述】:我目前正在熟悉 android,正在使用 Lunar Lander 示例。
我发现,如果您离开应用程序(例如,点击通话按钮),它将破坏底层表面(调用 surfaceDestroyed
)。
向后导航(这将触发onWindowVisibilityChanged
)应用程序将崩溃,因为它会尝试在不重新创建的情况下绘制到表面。
我可以在onWindowVisibilityChanged
(或其他任何地方)中添加一些代码来重新生成 SurfaceView 的底层表面并很好地恢复执行吗?
感觉这应该是一个简单的函数调用,但我在 API 文档中找不到任何内容。
谢谢!
【问题讨论】:
【参考方案1】:“mSurfaceExists = true”的这个解决方案对我也不起作用。看起来 surfaceCreated() 没有被调用,因为 super.onWindowVisibilityChanged() 没有被调用。所以没有创建表面并且它不会崩溃,因为 threas.start 没有被调用。
我认为问题是: 调用 thread.start() 会导致错误,因为线程已经启动。 但是在surfaceDestroyed() 中,thread.join 导致线程完成并死亡。并且线程一旦死了就无法重启。
我猜诀窍是在surfacecreated 中创建一个新线程,或者仅在用户调用应用程序完成(返回键)而不是暂停(home 键)时才导致线程完成。这可以通过在活动上调用 isFinishing() 来检查。
不确定这是否可行。我很快就会尝试这个。
【讨论】:
刚刚测试过(调试过),正如你所想的那样。只要应用程序被隐藏并且线程停止,surfaceDestroyed()
就会被调用。再次显示应用程序时,surfaceCreated()
被调用并尝试再次启动线程,这导致IllegalThreadStateException
。【参考方案2】:
误诊!应用程序会自动重新创建表面,但其中有一个调用会在创建之前尝试对其进行绘制。
解决问题:
boolean mSurfaceExists;
...
public void surfaceDestroyed(SurfaceHolder holder)
mSurfaceExists = false;
...
public void surfaceCreated(SurfaceHolder holder)
mSurfaceExists = true;
...
protected void onWindowVisibilityChanged(int visibility)
// only call base if there's a surface
if(mSurfaceExists)
super.onWindowVisibilityChanged(visibility);
现在一切都好起来了。 (据我所知,无论如何,如果这是不好的做法,Java/Android 专家可以随时发表评论!)
【讨论】:
我试过这个,但它没有正确绘制月球着陆器游戏。你得到的只是文字而不是宇宙飞船或背景。以上是关于Android:使用 SurfaceView 重新获得焦点的主要内容,如果未能解决你的问题,请参考以下文章
Android使用SurfaceView搭建OpenGL环境