首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> J2ME

J2ME 手機長按鍵/連續按鍵跨平台兼容方案:輪詢模擬實現

     編輯:J2ME

解決 S40/S60/國產機長按無響應:用獨立線程輪詢模擬 keyRepeated

J2ME 規範提供 Canvas.keyRepeated(int keyCode) 回調,但大量機型(如 Nokia 6600、許多國產機、部分麼 S40 機型)不支持。用戶長按方向鍵瀏覽長文本或遊戲移動角色時無連續事件,體驗極差。本文給出通用的「按下標記 + 獨立線程輪詢」方案,在不支持原生 keyRepeated 的機型上完美模擬長按連發。

核心原理

  1. keyPressed:記錄鍵碼,設置 isKeyDown = true,記錄 timeOut = System.currentTimeMillis()。
  2. keyReleased:設置 isKeyDown = false。
  3. 後台線程每 50ms 輪詢:若 isKeyDown 且距上次觸發 ≥ 300ms,觸發邏輯(如 repaint()、角色移動),更新 timeOut。

完整可運行示例

import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;

public class KeyRepeatMIDlet extends MIDlet {
    protected void startApp() {
        Display.getDisplay(this).setCurrent(new PollingCanvas());
    }
    protected void pauseApp() {}
    protected void destroyApp(boolean u) {}
}

class PollingCanvas extends Canvas {
    int keyCode;
    boolean isKeyDown;
    long lastRepeatTime;

    public PollingCanvas() {
        new Thread(() -> {
            while (true) {
                try { Thread.sleep(50); } catch (InterruptedException ignored) {}
                if (isKeyDown) {
                    long now = System.currentTimeMillis();
                    if (now - lastRepeatTime >= 300) { // 300ms 間隔 ≈ 3.3 次/秒
                        lastRepeatTime = now;
                        // 這裡放長按邏輯:移動、翻頁、自動射擊等
                        System.out.println("Simulated keyRepeated: " + keyCode);
                        repaint();
                    }
                }
            }
        }).start();
    }

    protected void keyPressed(int k) {
        keyCode = k; isKeyDown = true; lastRepeatTime = System.currentTimeMillis();
        repaint();
    }
    protected void keyRepeated(int k) { // 原生支持的機型會走這裡
        keyCode = k; repaint();
    }
    protected void keyReleased(int k) {
        isKeyDown = false; keyCode = k; repaint();
    }
    protected void paint(Graphics g) {
        g.setColor(0); g.fillRect(0, 0, getWidth(), getHeight());
        g.setColor(0xFFFFFF);
        g.drawString("Key: " + keyCode + (isKeyDown ? " [HOLD]" : ""), 10, 10, 0);
    }
}

關鍵參數調優

參數建議值說明
輪詢間隔 Thread.sleep()50 ms太小佔 CPU,太大響應延遲明顯
首次觸發延遲300~500 ms模擬鍵盤重複率,防止誤觸
後續觸發間隔100~150 ms可在代碼中區分首次/後續,實現「加速」手感

進階優化:區分原生與模擬

若機型支持原生 keyRepeated,輪詢線程會產生雙重觸發。解決方案:

boolean nativeRepeatSupported = false;
protected void keyRepeated(int k) {
    nativeRepeatSupported = true;
    // 原生邏輯
}

輪詢線程中檢查 if (!nativeRepeatSupported && isKeyDown) ...,僅在無原生支持時模擬。

適用場景

  • 遊戲:角色持續移動、自動連射、長按蓄力。
  • 文本瀏覽:長按上下鍵翻頁/滾動。
  • 菜單導航:長按快速跳轉選項。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved