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

Android Studio如何通过TextView实时持续显示动态更新的变量值

问题运行效果截图

问题根因

你的代码存在两个直接导致积分无法实时显示的问题:

  • Timer的定时任务运行在独立子线程,Android系统限制只有主线程(UI线程)可以操作View控件,子线程直接调用setText更新TextView会触发线程异常,更新逻辑根本不会生效
  • 你仅在onCreate页面初始化阶段给visibletotals赋值过一次,后续自动累加积分、点击加积分、升级扣积分的逻辑里,都没有同步更新这个总积分显示控件
修复方案
  • 新增主线程Handler,把定时任务里的UI更新逻辑切回主线程执行
  • 抽离统一的积分刷新方法,所有修改clicks积分值的位置都调用这个方法,避免漏更新
  • 补充页面销毁时的Timer取消逻辑,防止内存泄漏

直接替换为下面修正后的完整代码即可:

package com.example.idleclicker;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import java.util.Timer;
import java.util.TimerTask;


public class MainActivity extends AppCompatActivity {

    TextView points;
    TextView visibletotals;
    Button click;
    Button upgradebtn;
    TextView Leveltext;
    int clicks = 0;
    int clickcost = 10;
    int upgradelevel = 1;
    Timer myTimer = new Timer();
    // 主线程Handler,用于将子线程任务切到UI线程执行
    private final Handler mainHandler = new Handler(Looper.getMainLooper());

    /**
     * 统一刷新积分显示,所有修改clicks值的逻辑后都调用该方法
     */
    private void updatePointsShow() {
        points.setText(getResources().getString(R.string.evol) + clicks);
        visibletotals.setText("Evolutions Points: " + clicks);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        click = findViewById(R.id.click);
        points = findViewById(R.id.points);
        upgradebtn = findViewById(R.id.upgradebtn);
        Leveltext = findViewById(R.id.leveltext);
        visibletotals = findViewById(R.id.visibletotals);

        // 初始化页面显示
        updatePointsShow();
        upgradebtn.setText(getResources().getString(R.string.Upgrade) +
                clickcost +
                getString(R.string.LevelText)
                + upgradelevel);

        myTimer.schedule(new TimerTask() {
            @Override
            public void run() {
                clicks += upgradelevel;
                // 切到主线程刷新UI
                mainHandler.post(() -> updatePointsShow());
            }
        }, 0, 1000);


        click.setOnClickListener(view -> {
            clicks++;
            updatePointsShow();
        });

        upgradebtn.setOnClickListener(view -> {
            if (clicks >= clickcost) {
                clicks -= clickcost;
                upgradelevel += 1;
                clickcost *= 2;
                upgradebtn.setText(getResources().getString(R.string.Upgrade) +
                        clickcost +
                        getString(R.string.LevelText)
                        + upgradelevel);
                // 扣除升级积分后同步刷新显示
                updatePointsShow();
            }
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 页面销毁时取消定时任务,避免内存泄漏
        myTimer.cancel();
    }
}
注意事项
  • Android的UI操作必须在主线程执行,子线程直接修改View属性会抛出CalledFromWrongThreadException,这是平台基础规则
  • 统一抽离刷新方法可以减少重复代码,后续新增其他修改积分的逻辑(比如道具加成、离线收益结算)时,只要在修改clicks后调用updatePointsShow()即可,不需要重复写setText逻辑
  • 定时任务、异步任务必须在页面销毁时主动取消,否则会持有Activity引用导致内存泄漏,后台空跑也会额外消耗设备性能

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 07:51:27