You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Codename One中如何非阻塞式刷新UI上的分数计数器?

问题分析与解决方案

你的问题出在对EDT(事件调度线程)的使用方式上,我来拆解一下问题根源,然后给你两种可行的实现方案:

为什么你的代码会阻塞UI且不更新分数?

Display.getInstance().callSerially() 的作用是把传入的Runnable提交到EDT线程中执行,而EDT是Codename One中处理所有UI操作、用户交互事件(比如按钮点击)的核心单线程。

你在Runnable里写了while(true)无限循环,还加上Thread.sleep(100)——这会直接把EDT线程死死占住:它要么在循环里累加分数,要么在sleep,完全没时间去处理其他UI事件,也没法触发UI重绘来更新分数文本。这就是为什么按钮点不动、分数也不更新的原因。

正确实现方式1:使用Timer定时任务

这种方式更规范,也方便控制启停,适合大多数场景:

private Timer scoreUpdateTimer;

private void startScoreLoop() {
    // 初始化定时器,每100ms执行一次更新
    scoreUpdateTimer = new Timer();
    scoreUpdateTimer.scheduleAtFixedRate(new TimerTask() {
        @Override
        public void run() {
            // 后台线程中计算分数,然后切换到EDT更新UI
            Display.getInstance().callSerially(() -> {
                MyApplication.score += 1;
                gui_Score.setText(String.valueOf(MyApplication.score));
            });
        }
    }, 0, 100); // 参数:首次执行延迟0ms,之后每100ms执行一次
}

// 记得在Form销毁时停止定时器,避免内存泄漏
@Override
protected void onDispose() {
    if (scoreUpdateTimer != null) {
        scoreUpdateTimer.cancel();
        scoreUpdateTimer = null;
    }
    super.onDispose();
}

然后在Form的构造方法里调用startScoreLoop()即可。

正确实现方式2:递归式callSerially调度

这种方式更简洁,适合简单的循环更新场景:

private void updateScoreLoop() {
    Display.getInstance().callSerially(() -> {
        // 在EDT中更新UI
        MyApplication.score += 1;
        gui_Score.setText(String.valueOf(MyApplication.score));
        
        // 在后台线程等待100ms后,递归调用自己,实现循环
        Display.getInstance().scheduleBackgroundTask(() -> {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                // 中断时恢复中断状态,避免线程状态异常
                Thread.currentThread().interrupt();
                return;
            }
            updateScoreLoop();
        });
    });
}

同样在Form构造方法里调用updateScoreLoop(),它会自动循环更新分数,且不会阻塞EDT。

关键注意事项

  • 所有UI组件的修改必须在EDT中执行,所以后台线程的操作一定要通过callSerially()切换到EDT。
  • 如果使用Timer方式,一定要在Form销毁时停止定时器,否则会导致内存泄漏和不必要的资源消耗。

内容的提问来源于stack exchange,提问作者seinecle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:38:09