情况:Android
class GLRenderer implements GLSurfaceView.Renderer
..
void onDrawFrame(GL10 gl) {..}
class MainGLSurfaceView extends GLSurfaceView
..
setRenderer(new GLRenderer());
class MainActivity ..
..
boolean onTouchEvent(MotionEvent event) {..}
MainActivity.onTouchEvent接收和处理事件,其中一些事件会更改onDrawFrame(gl)使用的状态。
问1:在onDrawFrame返回之前,有没有一种方法可以"暂停消息队列"?
注意:在速度较慢的手机上,我的onDrawFrame可能需要大约1/3秒的时间。如果有必要,我可能会更改它,这样,如果它没有所需的信息,它就可以开始在后台获取,立即返回,然后在稍后的绘制请求(由计时器触发)中绘制新帧。
问1B:也许这些事件只是打断了抽签,因为我正在做一些获取数据的事情。事件可以在任何时候(在onDrawFrame中间)中断吗?还是只有当我的自定义onDrawFrame逻辑进行某些(系统?)调用时才会中断?
1B:不幸的是,通过一个断点,我捕捉到了在计算过程中中断的事件(只需要一个用于保存临时值的小类的新实例的VM"init"就可以了,这是"可中断的";几乎任何java代码都可能做到的)。所以我需要应付打断事件,不能回避它们。
问2:还是最好检查传入的消息,并以某种方式决定哪些消息应该立即处理,然后再处理?做什么?对于其他消息,在onDrawFrame返回后处理它们?
问题3:我在问题2中做了一个尝试,将消息放到一个内部队列中。然后我尝试在onDrawFrame方法的末尾处理它们。在出现试图打开确认对话框的消息之前,此操作一直正常。结果:RuntimeException:无法在未调用Looper.prepare()的线程内创建处理程序。是的,我认为我不应该这样做。我能以某种方式将这些消息推回到主消息队列吗?
(我不想再创建一个线程,所以在onDrawFrame结束时,我尝试了"new Handler().postDelayed(new Runnable()..",我打算在其中对这些事件做些什么。有同样问题的Oops无法在onDrawFrame运行的线程上创建处理程序。)
因此,我的基本想法是,我寻求一种方法,不从当前的画框下拉出地毯。我不想让所有事件触发的逻辑都在一组数据上工作,然后"冻结"该数据(复制它),这样绘制框架就可以在冻结的集上工作。
Q&我在问这个问题之前看了一眼:
安卓中的消息队列
本文讨论了创建一个looper和一个处理程序,包括指向另一篇文章的链接。我可能会对此进行调整,以创建一个附加到主线程的looper的处理程序。因此,我只需要将我的辅助队列传递给这个处理程序,并启动它运行,而不必重新注入MessageQueue。但是在我想要启动处理程序的时候,我在错误的线程上,所以不确定如何继续。嗯,也许做一个自定义事件,我会在主线程上触发它?
如何暂停活动?
显示了如何使用标志暂停工作线程。由于我有多种类型的事件要推迟,所以不用这种方法,更容易将这些事件(的副本)保存在单独的队列中。然后我只需要知道如何将它们"注入"到主MessageQueue中。我试图避免创建另一个线程,以尽量减少系统资源。
如何暂停线程';Android中的消息队列?
创建自己的线程时的替代方法(不使用活套),例如工作线程。这对我的情况没有帮助,即UI事件进入现有的looper。
如果有一些完全不同的方法来解决这个问题:
这不是所有使用GLSurfaceView渲染的人最终都会遇到的情况吗?
有没有一个强大的方法来处理gl绘图和异步GUI事件的例子?
我的"Q 3"解决方案的最后一部分:
public class MainActivity ...
// Call this, if not already on UI thread.
public static void processQueuedEventsOnUIThread() {
try {
Runnable runnable = new Runnable() {
@Override
public void run() {
... process the deferred UI events, which I have stored on a private queue ...
}
};
MainActivity.mMainActivity.runOnUiThread(runnable);
} catch (Exception e) {
Log.e("MainActivity", "processQueuedEventsOnUIThread", e);
}
}
我的GLRenderer.onDrawFrame()中的最后一条语句现在是
MainActivity.processQueuedEventsOnUIThread();
即使处理的事件导致对话框窗口(具有自己的处理程序)打开,也不会再发生异常。CCD_ 1是关键步骤。