You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

开发反应时间测算游戏时遇Timer-0致命异常求助

解决Android Timer线程操作UI导致的CalledFromWrongThreadException问题

嘿,这个问题我太熟了!你遇到的ViewRootImpl$CalledFromWrongThreadException是Android开发里的经典坑——你在Timer的后台线程里直接操作UI组件了

Android的UI组件有个严格的规则:只有创建视图层级的原始线程(也就是主线程/UI线程)才能修改视图。而Timer默认会在单独的后台线程执行任务,这就直接违反了这个规则,系统自然会抛出异常阻止你。

下面给你几个靠谱的解决方案,按推荐程度排序:

方案1:用Handler替代Timer(最推荐,符合Android线程模型)

Handler天生和UI线程绑定,用它来处理定时任务是最稳妥的方式:

// 在Activity里定义Handler和Runnable
private Handler uiHandler = new Handler(Looper.getMainLooper());
private Runnable timerTask = new Runnable() {
    private long elapsedTime = 0;

    @Override
    public void run() {
        // 这里直接就是UI线程,放心操作UI!
        elapsedTime += 100;
        yourButton.setText("当前耗时:" + elapsedTime + "ms");
        // 重复执行任务,间隔100ms
        uiHandler.postDelayed(this, 100);
    }
};

// 启动定时任务(比如在按钮点击时)
public void startGame(View view) {
    uiHandler.post(timerTask);
}

// 记得在页面销毁时停止任务,避免内存泄漏
@Override
protected void onDestroy() {
    super.onDestroy();
    uiHandler.removeCallbacks(timerTask);
}

方案2:用runOnUiThread在Timer任务里切换线程

如果你不想换掉Timer,可以把UI操作代码包裹在Activity的runOnUiThread方法里,强制切换到UI线程执行:

new Timer().scheduleAtFixedRate(new TimerTask() {
    private long elapsedTime = 0;

    @Override
    public void run() {
        // Timer的任务在后台线程,不能直接碰UI,所以切换到主线程
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                elapsedTime += 100;
                yourButton.setText("当前耗时:" + elapsedTime + "ms");
            }
        });
    }
}, 0, 100);

方案3:Kotlin项目用协程(最简洁)

如果你的项目是Kotlin开发的,用协程的Main调度器可以更优雅地解决问题:

import kotlinx.coroutines.*

// 在Activity/Fragment里启动协程
fun startGame() {
    lifecycleScope.launch(Dispatchers.Main) {
        var elapsedTime = 0L
        while (isActive) {
            delay(100)
            elapsedTime += 100
            yourButton.text = "当前耗时:$elapsedTime ms"
        }
    }
}

额外提醒

不管用哪种方案,都要记得在页面销毁时停止定时任务,不然会导致内存泄漏哦!

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

火山引擎 最新活动