Android:使用 SurfaceView 重新获得焦点

发布于 2024-07-15 18:46:49 字数 358 浏览 4 评论 0原文

我目前正在熟悉 Android,尝试 Lunar Lander 示例。

我发现,如果您离开应用程序(例如,点击通话按钮),它将破坏底层表面(调用surfaceDestroyed)。

向后导航(这将触发 onWindowVisibilityChanged)应用程序将崩溃,因为它将尝试绘制到表面而不重新创建它。

我可以在 onWindowVisibilityChanged (或其他任何地方)中放入一些代码来重新生成 SurfaceView 的底层表面并很好地恢复执行吗?

感觉这应该是一个简单的函数调用,但我在 API 文档中找不到任何内容。

谢谢!

I'm currently getting to grips with Android, playing around with the Lunar Lander sample.

I've found that if you navigate away from the app (eg, hit the call button) it will destroy the underlying surface (calling surfaceDestroyed).

Navigating back (which will trigger onWindowVisibilityChanged) the app will crash, as it will try to draw to the surface without recreating it.

Is there some code I can put in onWindowVisibilityChanged (or anywhere else) that will regenerate the SurfaceView's underlying surface and resume execution nicely?

It feels like this should be a simple function call but I can't find anything in the API docs.

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

玉环 2024-07-22 18:46:49

“mSurfaceExists = true”的这个解决方案也不适合我。 看起来 SurfaceCreated() 没有被调用,因为 super.onWindowVisibilityChanged() 没有被调用。 因此没有创建表面,也不会崩溃,因为 threas.start 没有被调用。

我相信问题是:
调用 thread.start() 会导致错误,因为线程已经启动。
但在 surfaceDestroyed() 中,thread.join 会导致线程完成并终止。 并且线程一旦死亡就无法重新启动。

我猜测技巧是在 surfacecreated 中创建一个新线程,或者仅在用户调用应用程序完成(后退键)而不是暂停(主页键)时才导致线程完成。 这可以通过在活动上调用 isFinishing() 来检查。

不确定这是否有效。 我很快就会尝试这个。

This solution for "mSurfaceExists = true" isn't working for me either. It looks like surfaceCreated() is not getting called because super.onWindowVisibilityChanged() is not called. So there is no surface created and it doesn't crash because threas.start is not called.

I believe the problem is:
Calling thread.start() causes the error because the thread was already started.
But in surfaceDestroyed(), thread.join causes the thread to complete and die. And a thread can not be restarted once dead.

I am guessing the trick is to create a new thread in surfacecreated or to only cause the thread to complete when user is calling the application to finish(back key) and not pausing(home key). This can be checked by calling isFinishing() on the activity.

Not sure if this will work. I will be trying this soon.

新雨望断虹 2024-07-22 18:46:49

误诊! 应用程序会自动重新创建表面,但其中有一个调用会在创建表面之前尝试对其进行绘制。

解决问题:

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 专家如果这是不好的做法,请随时发表评论!)

Mis-diagnosis! The app re-creates the surface automatically, but there's a call in there that tries to draw to it before it's created.

Fixing the problem:

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);
}

Now it's all swell. (as far as I'm aware, anyway - Java/Android experts feel free to comment if this is bad practise!)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文