【问题标题】:Android - Ending activity from within rendering threadAndroid - 从渲染线程中结束活动
【发布时间】:2010-11-29 15:00:08
【问题描述】:

下午好。

我不熟悉 android 中的活动生命周期,并且一直在尽可能地阅读,但我不知道如何以一种好的方式解决以下问题。

我有一个带有 GLSurfaceView 的活动,可以在屏幕上绘制各种东西。在这个 GLSurfaceView 的渲染线程中,我执行所有渲染以及实际的更新逻辑(我最终将把它分开)。

我遇到的麻烦来自渲染器中绘制的“屏幕”之一,我希望结束 Activity 并让它调用各种生命周期方法。

通常我可以用 System.exit(0);但是以这种方式结束活动似乎不会调用 OnStop(); OnDestroy();方法。

这可能只是我很傻,没有看到这样做的简单方法,但有没有办法访问 Activity 并调用 activity.finish();不必一直向下传递对它的引用?

这可能不是一个 android 问题,而是一个一般 java 问题?对不起,我对两者都有点生疏。也许有人可以大致解释一下他们如何在他们的应用中处理此类问题。

【问题讨论】:

    标签: java android android-activity lifecycle renderer


    【解决方案1】:

    您确实需要遵守线程安全规则,而不是直接从渲染线程调用 activity.finish()。处理此问题的最佳方法是将可运行对象发布回 UI 线程的事件队列。然后让 Runnable 调用 activity.finish()。

    您不必将活动传递到您计划停止活动的区域。这就是我要做的。将活动传递给您在 onCreate() 中实例化的类。比如:

    public void onCreate( ... ) {
       MyRenderer renderer = new MyRenderer( glSurface, this );
    }
    

    然后在 MyRenderer 中,我会执行以下操作:

    public void someMethodInRenderer() {
       if( stop ) {
          stop();
       }
    }
    
    public void stop() {
       Handler handler = new Handler();
       handler.post( new Runnable() {
          public void run() {
             activity.finish();
          }
       } );
    }
    

    注意用于回发到 UI 线程的处理程序。这样就可以安全地调用 activity.finish()。我在文档中找不到任何具体信息,说明从另一个线程调用 finish() 是安全的还是不安全的,所以为了安全起见,将其发回。

    注意事项。如果 someMethodInRenderer() 在您的程序的内部深处,那么您不必直接访问活动实例。您只需要一个引用,以便最终调用该活动来完成。因此,也许有对系统另一部分的引用,您正在传递给该方法,您可以在其中添加 stop()。所以 stop() 和 someMethodInRenderer() 可以在同一个类中,也可以在不同的类中。这是你必须做出的选择。最终,这是您必须决定的架构问题。

    【讨论】:

    • 谢谢,我刚回来编辑我的问题并提出“这可能更像是一个架构/最佳实践问题”。自学成才,我倾向于知道做某事的方法,但总是怀疑这样做是否是最佳做法,甚至是否安全!
    • 对此有点困惑,我意识到您需要在 UI 线程中创建处理程序,所以在 OnCreate() 中,否则它是在渲染线程中创建的并且无法回发?对吗?
    • 是的,我相信您可能必须在 UI 线程上创建处理程序,然后将其传递给您的渲染器。同样,您可以通过在架构的各个部分路由调用来使用架构技巧,这样您就不必一直将引用传递到调用 stop() 的位置。
    【解决方案2】:

    如果渲染线程在Activity内部,可以使用ActivityClassName.this.finish();

    【讨论】:

      【解决方案3】:

      解决我遇到的问题:

      如果您通过activity.finish() 完成您的活动(包括从另一个线程),重要的是渲染线程的onDraw() 方法不会被阻塞(由于我实现了双缓冲区而发生在我身上渲染)。

      在这种情况下,只有活动类中的onPause() 方法被调用。即使应用程序以很短的延迟结束,也没有调用方法 onStop()onDestroy()

      希望这可以帮助任何面临同样问题的人。

      编辑:原因是,在我的activity.onPause() 方法中,我调用了glSurfaceView.onPause(),而渲染线程的onDraw() 被阻塞了。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-08-27
        • 1970-01-01
        • 1970-01-01
        • 2012-07-13
        相关资源
        最近更新 更多