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

非Activity类更新TextView致应用崩溃,寻求技术解决方案

嗨,我一眼就看出问题出在哪啦!你在GameLogic里直接new了一个OnePlayerGameActivity的实例,这可是Android开发里的大忌啊!

为什么会崩溃?

Android的Activity是由系统负责实例化和管理生命周期的,你手动new OnePlayerGameActivity()出来的对象根本没有经过onCreate等生命周期方法,布局都没加载完成,findViewById(R.id.game_result_textView)自然会返回null,接着调用result.setText("LOST")就会触发NullPointerException,直接导致应用崩溃。

正确的解决方案:用接口回调解耦

咱们要把UI更新的逻辑交还给Activity本身,同时让GameLogic只负责处理游戏逻辑,通过接口回调的方式通知Activity更新TextView。具体步骤如下:

1. 定义游戏结果回调接口

可以在GameLogic类内部或者单独创建一个接口文件:

public interface GameResultListener {
    // 用来传递游戏结果文本的方法
    void onGameResult(String resultText);
}

2. 修改GameLogic类,持有接口引用而非Activity

把直接操作Activity和TextView的代码去掉,换成通过回调通知:

public class GameLogic {
    private GameResultListener mResultListener;
    private int mPlayerStat = 0;
    private int mOpponentStat = 0;
    private int mPlayerChoice;

    // 提供方法设置回调监听
    public void setGameResultListener(GameResultListener listener) {
        mResultListener = listener;
    }

    public void gameResult() {
        getPlayerChoice();
        int computer = computerChoice();
        String resultText = "";

        if (mPlayerChoice == computer) {
            mPlayerStat += 0;
            mOpponentStat += 0;
            resultText = "DRAW";
        } else if (mPlayerChoice == 1) { // ROCK
            switch (computer) {
                case 2: // PAPER
                    mOpponentStat++;
                    resultText = "LOST";
                    break;
                case 3: // SCISSORS
                    mPlayerStat++;
                    resultText = "WIN";
                    break;
            }
        }
        // 这里可以补充其他玩家选择的逻辑(比如PAPER、SCISSORS的情况)

        // 游戏结果确定后,通过回调通知Activity更新UI
        if (mResultListener != null) {
            mResultListener.onGameResult(resultText);
        }
    }

    // 你的其他方法:getPlayerChoice()、computerChoice()等
    private void getPlayerChoice() {
        // 你的实现逻辑
    }

    private int computerChoice() {
        // 你的实现逻辑
        return 0;
    }
}

3. 在OnePlayerGameActivity中实现回调接口

在Activity里初始化TextView,并实现回调方法来更新UI:

public class OnePlayerGameActivity extends AppCompatActivity implements GameResultListener {
    private TextView mResultTextView;
    private GameLogic mGameLogic;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.your_game_activity_layout); // 替换成你的布局文件名

        // 初始化TextView,这时候布局已经加载,findViewById不会返回null
        mResultTextView = findViewById(R.id.game_result_textView);

        // 初始化GameLogic并设置回调监听
        mGameLogic = new GameLogic();
        mGameLogic.setGameResultListener(this);
    }

    // 实现回调方法,在这里更新TextView
    @Override
    public void onGameResult(String resultText) {
        mResultTextView.setText(resultText);
    }

    // 比如在游戏结束的触发点调用gameResult()方法
    public void triggerGameResult() {
        mGameLogic.gameResult();
    }

    // 注意:Activity销毁时移除回调,避免内存泄漏
    @Override
    protected void onDestroy() {
        super.onDestroy();
        mGameLogic.setGameResultListener(null);
    }
}

这样修改后,GameLogic只专注于游戏逻辑,UI更新的事情交给Activity处理,既避免了崩溃,又符合Android的架构规范,还能防止内存泄漏~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:48:39