Android应用空指针异常:调用TextView.setText时报错求助
我一眼就看到了问题的核心——你在ScoreSetter类里犯了一个Android开发的常见错误:手动创建了一个新的MainGame实例,而不是使用系统正在运行的那个Activity对象。
问题根源
在ScoreSetter里你写了:
private MainGame mainGame = new MainGame();
但Android的Activity实例是由系统框架负责创建和管理的,你手动new出来的这个MainGame对象,它的onCreate方法从来没有被调用过,自然也不会执行initializeLayoutViews()去初始化gameScoreP1这个TextView控件。所以当你调用mainGame.writeGameScoreP1(indexP1)时,gameScoreP1还是null,执行setText就触发了空指针异常。
至于日志能输出MainGame_value:1,是因为你在writeGameScoreP1里先打印了日志,之后才调用setText,所以日志能正常输出,但紧接着就崩溃了。
修复步骤
1. 修改ScoreSetter,传入真实的Activity实例
把ScoreSetter里手动创建MainGame的代码删掉,改成通过构造方法接收当前运行的MainGame实例:
class ScoreSetter { private int[] GAME_SCORE_VALUES = new int[] {0, 15, 30, 40}; private int indexP1 = 0; private int indexP2 = 0; private int gameScoreP1; private int gameScoreP2; public String gameValueP1; private String gameValueP2; // 改为持有MainGame的引用,不再自己实例化 private MainGame mainGame; // 构造方法接收MainGame实例 ScoreSetter(MainGame mainGame){ this.mainGame = mainGame; } public void initIndex() { indexP2 = 0; indexP1 = 0; } public void initAfterGameWon() { } public void clickedByP1() { // 注意:这里应该使用GAME_SCORE_VALUES里的值,而不是直接传indexP1 // 同时要避免数组越界 if(indexP1 < GAME_SCORE_VALUES.length - 1) { ++indexP1; mainGame.writeGameScoreP1(GAME_SCORE_VALUES[indexP1]); } } }
2. 在MainGame中创建ScoreSetter时传入当前实例
修改MainGame里创建ScoreSetter的代码,把this(当前Activity实例)传进去:
// 原来的代码: // final ScoreSetter scoreSetter = new ScoreSetter(this); // 改成: final ScoreSetter scoreSetter = new ScoreSetter(MainGame.this);
3. 额外优化:避免数组越界
你的GAME_SCORE_VALUES数组长度是4(索引0-3),如果不做判断,indexP1递增到4时会触发数组越界异常,所以我在上面的clickedByP1方法里加了判断,确保索引不会超出数组范围。
这样修改后,点击gameScoreP1时,就会操作系统正在运行的MainGame实例里的TextView,不会再出现空指针崩溃了。
内容的提问来源于stack exchange,提问作者Andy

