当按下多个键时,Android不会调用onKeyUp

时间:2016-03-04 19:59:55

标签: java android keyboard-events

我正在JavaAndroid编写一个小游戏,我在处理输入方面遇到了麻烦。对于早期测试,我使用硬件键盘输入,但我打算最终使用游戏手柄控件。

我遇到的问题是这样的:当用户持有一个key超过10秒钟时,同时按下并释放许多其他键,onKeyUp()函数用于此第一个密钥在最终发布时不会被调用。

我还没有找到一个完全最小的复制品,但是我可以在两个不同的emulators和一个物理Nexus 5(带有自称为键盘的游戏手柄)上可靠地触发它。

相关代码,删除了冗余和日志语句:

public class GameSurfaceView extends GLSurfaceView {
    public final static short VBTN_FORWARD      = 0;
    public final static short VBTN_BACKWARD     = 1;
    // snipped several more similar constants
        public AtomicIntegerArray virtual_button_state = new AtomicIntegerArray(7);

    @Override
    public boolean onKeyDown(int keyCode, @NonNull KeyEvent event){
        if (event.isLongPress() || event.getRepeatCount() > 0){
            return true;
        }
        switch (keyCode) {
            case KeyEvent.KEYCODE_DPAD_UP:
            case KeyEvent.KEYCODE_W:
                virtual_button_state.incrementAndGet(GameRenderer.VBTN_FORWARD);
                return true;
            case KeyEvent.KEYCODE_DPAD_DOWN:
            case KeyEvent.KEYCODE_S:
                virtual_button_state.incrementAndGet(GameRenderer.VBTN_BACKWARD);
                return true;
            // snipped several more similar cases
        }
    }

    @Override
    public boolean onKeyUp(int keyCode, @NonNull KeyEvent event){
        switch (keyCode) {
            case KeyEvent.KEYCODE_DPAD_UP:
            case KeyEvent.KEYCODE_W:
                virtual_button_state.decrementAndGet(GameRenderer.VBTN_FORWARD);
                return true;
            case KeyEvent.KEYCODE_DPAD_DOWN:
            case KeyEvent.KEYCODE_S:
                virtual_button_state.decrementAndGet(GameRenderer.VBTN_BACKWARD);
                return true;
            // snipped several more similar cases
        }
    }
}

我已经做了大量的测试,并且跟踪语句显示onKeyUp()在 所有中都没有被称为。无论问题是什么,它都会阻止事件首先到达我的GLSurfaceView。

可能相关的其他信息:

  • 我的活动是全屏但没有标题
  • 我的渲染器在RENDERMODE_CONTINUOUSLY
  • 中运行
  • 我的渲染器尚未进行优化,并经常跳帧
  • 我正在同时处理触摸事件
  • 此问题在正常游戏中经常出现。如果这个问题无法解决,那么这个项目已经死了。

1 个答案:

答案 0 :(得分:0)

问题得到解决 - 错误并不像我最初描述的那样。我编写的测试代码中有一个微妙的错误,用于检测焦点是否丢失,这导致我对问题原因的错误结论。

事实上焦点在触摸事件期间丢失,有时在keyUp事件触发时没有恢复。多个同时发生的关键事件使这更有可能,这就是为什么错误地包含在repro中,以及为什么我错误地关注多个按键而不是同时触摸事件。

问题的最终原因是未能在我的视图构造函数中调用setFocusableInTouchMode(true)。