【问题标题】:Android: Regaining focus using SurfaceViewAndroid:使用 SurfaceView 重新获得焦点
【发布时间】:2010-10-14 21:54:25
【问题描述】:

我目前正在熟悉 Android,正在使用 Lunar Lander 示例。

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

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

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

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

谢谢!

【问题讨论】:

    标签: java android surfaceview


    【解决方案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 专家可以随时发表评论!)

    【讨论】:

    • 我试过这个,但它没有正确绘制月球着陆器游戏。你得到的只是文字而不是宇宙飞船或背景。
    猜你喜欢
    • 2011-08-11
    • 1970-01-01
    • 1970-01-01
    • 2011-03-08
    • 2012-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-27
    相关资源
    最近更新 更多