【问题标题】:Android: Touch seriously slowing my applicationAndroid:触摸严重减慢我的应用程序
【发布时间】:2010-12-03 04:26:59
【问题描述】:

我一直在研究这个问题。

当我运行我的应用程序(opengl 游戏)时,一切都很好,但是当我触摸屏幕时,我的应用程序速度变慢了(在 nexus 等功能强大的手机上并不明显,但在 htc 魔术上它变得很烦人) .

我做了一个跟踪,发现触摸事件似乎是在不同的线程中处理的,即使它不需要太多的处理时间,我认为机器人在线程之间切换的能力也不是很好......

当速度成为问题时,处理触摸的最佳方法是什么?

目前我正在使用: 在 GLSurfaceView 中

@Override
 public boolean onTouchEvent(MotionEvent event) {
     GameHandler.onTouchEvent(event);
     return true;
 }

欢迎提出意见

【问题讨论】:

标签: android touch


【解决方案1】:

我觉得下面的错误报告可能是相关的。可悲的是,它似乎只能在姜饼中修复。

Bug report

刚刚看到 SO 更喜欢答案中的详细信息,以防链接消失等。以上指的是 Google 接受的 Adnroid 2.1 中的错误,目标是在姜饼版本中进行修复。

问题 7836:system_server 消耗过多的 CPU 处理触摸事件

【讨论】:

    【解决方案2】:

    我自己不能保证这一点,但我的研究表明,触摸屏幕会触发如此多的事件,以至于它会淹没事件队列,因此会滞后于 CPU 占用你的资源。

    试试看:-

       try {
            Thread.sleep(16);
        } catch (InterruptedException e) {} //ignore
    

    在 onTouch 方法中的任何 返回 之前(通常只有最后一个 - 但只是确保)。我知道睡眠通常是一件非常糟糕的事情,但它不在 UI 线程中,所以应该没问题。睡眠 16 应将 FPS 限制为 60。

    【讨论】:

    • 快速问题:这应该适用于所有触摸事件吗?
    【解决方案3】:

    不要对 onTouchEvent() 进行大量计算。 OnTouchEvent 可以每根手指每秒触发数十或数百次,您应该将繁重的计算推迟到游戏的其他部分(例如物理引擎或图形引擎)。尤其要避免在 onTouchEvent 中绘图。

    您最好使用 onClickEvent 或其他不太密集的鼠标事件,并且仅在您确实需要跟踪触摸运动时才使用 onTouchEvent。

    【讨论】:

    • 我实际上并没有在那里进行任何繁重的计算(通常,我会仔细检查)我收集位置并更新我在屏幕上拖动的对象,或者我测试手指向下的位置及以上...
    【解决方案4】:

    @杰森:

    这将是一条评论,但它变得太大了,与我刚刚给出的答案不同[更好]。

    我已经使用这里描述的这种方法更改了我的实现 http://obviam.net/index.php/the-android-game-loop/

    通过使用上述方法意味着您不需要休眠 OnTouch 事件。

    别忘了保护你的游戏循环线程,这里提到http://wonton-games.blogspot.com/2010/06/lunar-lander-resume-game-workaround.html

    还要记住,Chris Pruett 在编写 Replica Island 时说他使用了 2 个线程,一个用于 update(),另一个用于 render() - 两者都必须受到保护。

    Chris 确实让他的 OnTouch 睡眠时间为 16 毫秒 (60 fps) 以减少事件 - 所以我会说如果您仍然需要减少事件,最好尝试一下 - 您只需要在事情发生时触摸屏幕看看它是否滞后并因此在放开时加速。

    为了我目前的需要,我使用的线程与我尚未进入 OpenGL 的线程相同,我仍然使用画布。但是当我使用 OpenGL 时,它将是 2 个线程,每个线程都是一个完整的类。

    最后,我不是通过计算帧来为我的精灵计时,而是用计时器包裹它们。我将分享我的课程并向您展示我如何称呼它。请记住,我还是 Java 新手,因此为糟糕的代码道歉。

    package com.yourname.yourapplication;
    
    //Used for doing something after a set time
    public class TimeDo {
        private int mRepeat = 0; //Stores the last wait period for the reset() later
        private long mTime = 0; //The goal time of when its due
        private boolean mFlagged = false; //Stop them getting a second true on a subsequent check
    
        public TimeDo(int milliseconds) {
            reset(milliseconds);
        }
    
        public TimeDo() {
            this(0);
        }
    
        public void reset(int milliseconds) {
            mRepeat = milliseconds;
            mTime = System.currentTimeMillis() + milliseconds;
            mFlagged = mRepeat==0; //ignore if zero
        }
    
        public void reset() { //Set it back to the delay used last time 
            reset(mRepeat);
        }
    
        public boolean check() {
            if (mFlagged) //Assert: shouldn't really happen
                return false;
            mFlagged = System.currentTimeMillis() > mTime; 
            return mFlagged;
        }
    
        public boolean checkAndReset() {
            if (check()) {
                reset();
                return true;
            }
            return false; //note mFlagged could be true here, so don't use it
        }
    
    }
    

    它是这样实现的:-

    public class Gem {
        private TimeDo mMoveGem = new TimeDo(100); //move 10 times a second, 100ms 
        private int mX = 0;
        private int mY = 0;
        private int mMoveX = 3;
        private int mMoveY = 4;
        .
        .
        .   
        public void update() {
            if (mMoveGem.checkAndReset()) {
                mX += mMoveX;
                mY += mMoveY;
                .
                .
            }
        }
    
        public void render(Canvas canvas) {
        //etc etc
            .
            .
        }
    
    }
    

    希望对您有所帮助! 抱歉,如果您必须重写很多应用程序 - 我做到了。

    编辑:TimeDo 类不是 postDelayed 可运行的,就像自动警报一样。如果您不检查,则不会触发任何“事件”。您可能会感到兴奋并让它创建一个可运行对象并将一个驻留在您的类中的回调方法传递给它(想想 OnClick 方法) - 但会破坏运行更新所有组件的独占 time-able update() 线程的目的。

    【讨论】:

      猜你喜欢
      • 2021-04-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多