简体   繁体   English

Android - 从渲染线程中结束活动

[英]Android - Ending activity from within rendering thread

Good afternoon. 下午好。

I am unfamiliar with the activity life cycle in android and have been reading up as best as possible but I cannot figure how to solve the following in a nice manner. 我不熟悉android中的活动生命周期并尽可能地阅读,但我无法想出如何以一种很好的方式解决以下问题。

I have an activity with a GLSurfaceView to draw various things on the screen. 我有一个带有GLSurfaceView的活动,可以在屏幕上绘制各种内容。 In the renderering thread for this GLSurfaceView I perform all the rendering as well as the actual update logic (I will seperate this out eventually). 在这个GLSurfaceView的渲染线程中,我执行所有渲染以及实际更新逻辑(我最终会将其分离出来)。

The trouble I am having is from one of the "screens" drawn within the renderer I wish to end the Activity and have it call the various lifecycle methods. 我遇到的麻烦来自渲染器中绘制的一个“屏幕”我希望结束Activity并让它调用各种生命周期方法。

Normally I might do this with System.exit(0); 通常我可以使用System.exit(0)执行此操作; however ending the activity in this way does not seem to call the OnStop(); 但是以这种方式结束活动似乎并没有调用OnStop(); OnDestroy(); 的OnDestroy(); methods. 方法。

This might just be me being silly and not seeing an easy way of doing this but is there a way to access the Activity and call activity.finish(); 这可能只是我愚蠢而没有看到这样做的简单方法,但有没有办法访问Activity并调用activity.finish(); without having to pass the reference to it all the way down? 无需将参考文件一直传递下去?

This is probably less of an android question and more a general java problem? 这可能不是一个Android问题,更像是一般的java问题? Sorry I am a little rusty at both. 对不起,我两个都有点生疏了。 Maybe if someone could explain roughly how they handle an issue like this in their app. 也许如果有人能够大致解释他们如何在他们的应用程序中处理这样的问题。

You do need to obey thread safety rules and not call activity.finish() directly from your render thread. 您需要遵守线程安全规则,而不是直接从渲染线程调用activity.finish()。 The best way to handle this is to post a runnable back onto the event queue for the UI Thread. 处理此问题的最佳方法是将runnable发布回UI线程的事件队列。 And let that Runnable call activity.finish(). 让Runnable调用activity.finish()。

You don't have to pass the activity down to the area where you plan on stopping the activity. 您不必将活动传递到计划停止活动的区域。 Here is what I'd do. 这就是我要做的。 Pass the activity to the class you instantiate in onCreate(). 将活动传递给您在onCreate()中实例化的类。 Something like: 就像是:

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

Then inside MyRenderer I'd do something like: 然后在MyRenderer里面我做了类似的事情:

public void someMethodInRenderer() {
   if( stop ) {
      stop();
   }
}

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

Notice the Handler used to post back to the UI thread. 请注意Handler用于回发到UI线程。 That makes it safe to call activity.finish(). 这样可以安全地调用activity.finish()。 I couldn't find any specific information in the docs stating it's safe or not safe to call finish() from another thread so to be on the safe side post it back. 我在文档中找不到任何具体信息,说明从另一个线程调用finish()是安全的或不安全的,所以在安全方面发布它。

Things to keep in mind. 要记住的事情。 If someMethodInRenderer() is deep within the bowels in your program then you don't have to have access directly to the activity instance. 如果someMethodInRenderer()深入程序的内部,那么您不必直接访问活动实例。 You just need a reference so something that eventually calls to the activity to finish. 你只需要一个引用,最终调用活动来完成。 So maybe there is a reference to another part of the system you are passing down to that method where you can add the stop(). 所以可能有一个对系统的另一部分的引用,你传递给那个你可以添加stop()的方法。 So stop() and someMethodInRenderer() could be in the same class, or in different classes. 所以stop()和someMethodInRenderer()可以在同一个类中,也可以在不同的类中。 That's a choice you'll have to make. 这是你必须做出的选择。 Eventually this is an architecture issue you have to decide. 最终这是一个你必须决定的架构问题。

To address an issue I ran into: 为了解决我遇到的问题:

If you finish your activity (including from another thread) via activity.finish() it is important that the render thread's onDraw() method is not blocked (happened to me due to my implementation of double buffer rendering). 如果你通过activity.finish()完成你的活动(包括从另一个线程),重要的是渲染线程的onDraw()方法没有被阻止 (由于我实现双缓冲区渲染而发生在我身上)。

In that case, only the onPause() method in the activity class got called. 在这种情况下,只调用activity类中的onPause()方法。 The methods onStop() and onDestroy() weren't called even though the app finished with a short delay. 即使应用程序以短暂延迟结束,也不会调用onStop()onDestroy()方法。

Hope this helps anybody facing the same problem. 希望这有助于任何人面临同样的问题。

Edit: The reason was, that in my activity.onPause() method I called glSurfaceView.onPause() while the render thread's onDraw() was blocked. 编辑:原因是,在我的activity.onPause()方法中,我在调用渲染线程的onDraw()时调用了glSurfaceView.onPause()

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM