简体   繁体   English

为什么触摸事件会破坏我的Android帧速率?

[英]Why are touch events destroying my Android framerate?

I'm developing a game for Android. 我正在为Android开发游戏。 It's got a lot going on but is running reasonably smoothly. 它有很多事情发生但运行得相当顺利。 That is, of course, until the user touches the screen. 也就是说,直到用户触摸屏幕。

While they're touching it, onTouchEvent is called (with action = ACTION_MOVE , x = 0 and y = 0 ) roughly once every ten milliseconds at what appears to be a fairly high priority, as it absolutely obliterates the framerate. 当他们触摸它时, onTouchEvent被调用(使用action = ACTION_MOVEx = 0y = 0 )大约每10毫秒调用一次似乎相当高的优先级,因为它绝对会消除帧速率。 As soon as the touch ends the framerate returns to its nice state. 一旦触摸结束,帧速率就会恢复到良好状态。

I've tried 我试过了

  • having onTouchEvent handle input for the game as usual 像往常一样让onTouchEvent处理游戏输入
  • having onTouchEvent return true straight away onTouchEvent返回true
  • not having onTouchEvent implemented at all 没有实现onTouchEvent

The problem persists in all three situations. 这三种情况都存在问题。

Has anyone encountered this? 有没有遇到过这个? Is there a way to reduce the rate at which ACTION_MOVE events are generated, or to ensure that they're only generated when there is actual movement, or use a polling method that just gets the current location of the touch? 有没有办法降低生成ACTION_MOVE事件的速率,或者确保它们仅在实际移动时生成,或者使用仅获取触摸当前位置的轮询方法? Or even just a way to disable it entirely? 或者甚至只是一种完全禁用它的方法?

Read this thread. 阅读这个主题。 Basically you want to sleep the event thread since otherwise the system will pump a lot of events (between x,y and pressure there is always some movement going on) that you need to handle. 基本上你想要睡觉事件线程,否则系统会输出你需要处理的很多事件(在x,y和压力之间总会有一些运动)。

I've been trying to follow everything you guys have been talking about, but I must admit that after trying several ways of implementing what you suggest, I still haven't been able to achieve any positive results. 我一直在努力追随你们所谈论的一切,但我必须承认,在尝试了几种方法来实现你的建议之后,我仍然无法取得任何积极成果。 Could one of you provide some example code? 你们其中一个可以提供一些示例代码吗? Specifically, I'd like to know how to go about making the main/UI thread sleep. 具体来说,我想知道如何使主/ UI线程睡眠。 If it's applicable to my games, it would also be nice to know how to set up a polling model like Jon implemented. 如果它适用于我的游戏,那么知道如何设置像Jon实施的轮询模型也会很好。

Here's what my code looks like. 这是我的代码的样子。 On the UI thread: 在UI线程上:

public boolean onTouchEvent(MotionEvent event) {
    // Store event somewhere the game thread can see it:
    // ...

    synchronized (someObject) {
        try {
            someObject.wait(1000L);
        } catch (InterruptedException e) {
        }
    }

    return true;
}

and on the Game thread: 并在游戏线程上:

void myGame() {
    while (!stopping) {
        // ...

        // Get a touch event:
        synchronized (someObject) {
            someObject.notify();
        }
        Thread.yield();

        // ...
    }
}

Generally events comes with a timestamp property so it's easy to compute and throttle event rate. 通常,事件带有时间戳属性,因此可以轻松计算和限制事件率。

 if (currentEventTimestamp - lastEventTimestamp > 500) { lastEventTimestamp = currentEventTimestamp; // do something } 

Perhaps a somewhat obvious solution, but... have you tried only handling about 1/10 of them? 也许是一个有点明显的解决方案,但是......你试过只处理大约1/10的问题吗? If you're doing processing that's triggered every 10ms on the UI thread, that's likely going to slow down the framerate, yes. 如果你正在进行在UI线程上每10ms触发一次的处理,那么可能会降低帧速率,是的。 So what if you just accumulate a counter somewhat instead and only do any processing once that's gotten past some minimal threshold? 那么如果你只是稍微积累一个计数器而只是在经过一些最小阈值后才进行任何处理呢?

If you want a solution without having to deal with synchronizing threads I can recommend using the Handler interface to send the event and relevant data using a Message/Bundle to the game rendering thread. 如果你想要一个解决方案而不必处理同步线程我可以建议使用Handler接口将事件和相关数据使用Message / Bundle发送到游戏渲染线程。 The sleep workaround hinted here still applies. 这里暗示的睡眠解决方法仍然适用。

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

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