简单的井字游戏
Simple tictactoe game
我创建了一个简单的井字游戏。 gradle
构建没有错误,并且生成了 apk
。
但是在我的 phone 中安装后它显示如下...
java.lang.RuntimeException:
无法启动activity
ComponentInfo{com.codec.dnv.tictactoe/com.codec.dnv.tictactoe.MainActivity}: java.lang.NullPointerException:
Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2814) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892) at android.app.ActivityThread.-wrap11(Unknown Source:0) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1613) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:173) at android.app.ActivityThread.main(ActivityThread.java:6634) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:822)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference at com.codec.dnv.tictactoe.MainActivity.onCreate(MainActivity.java:42) at android.app.Activity.performCreate(Activity.java:7074) at android.app.Activity.performCreate(Activity.java:7065) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1215) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2767)>
如何克服这个问题?
您在此处为您的 OnClickListener 设置了空值
android.widget.Button.setOnClickListener(android.view.View$OnClickListener)
我会尝试确定它为什么为空,也许它从未被初始化。我们需要查看完整的代码块才能进一步帮助您。
public class MainActivity 扩展 AppCompatActivity 实现 View.OnClickListener {
private Button[][] buttons = new Button[3][3];
private boolean player1Turn = true;
private int roundCount;
private int player1Points;
private int player2Points;
private TextView player1;
private TextView player2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
player1 = findViewById(R.id.player1);
player2 = findViewById(R.id.player2);
for (int x = 0; x < 3; x++) {
for (int y = 0; y < 3; y++) {
String buttonID = "button_" + x + y;
int resID = getResources().getIdentifier(buttonID, "id", getPackageName());
buttons[x][y] = findViewById(resID);
buttons[x][y].setOnClickListener(this);
}
}
Button buttonReset = findViewById(R.id.button_reset);
buttonReset.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
resetGame();
}
});
}
@Override
public void onClick(View v) {
if (!((Button) v).getText().toString().equals("")) {
return;
}
if (player1Turn) {
((Button) v).setText("X");
} else {
((Button) v).setText("Y");
}
roundCount++;
if (checkWin()) {
if (player1Turn) {
player1Wins();
} else {
player2Wins();
}
} else if (roundCount == 9) {
draw();
} else {
player1Turn = !player1Turn;
}
}
private boolean checkWin() {
String[][] field = new String[3][3];
for (int x = 0; x < 3; x++) {
for (int y = 0; y < 3; y++) {
field[x][y] = buttons[x][y].getText().toString();
}
}
for (int x = 0; x < 3; x++) {
if (field[x][0].equals(field[x][1])
&& field[x][0].equals(field[x][2])
&& !field[x][0].equals("")) {
return true;
}
}
for (int x = 0; x < 3; x++) {
if (field[0][x].equals(field[1][x])
&& field[0][x].equals(field[2][x])
&& !field[0][x].equals("")) {
return true;
}
}
if (field[0][0].equals(field[1][1])
&& field[0][0].equals(field[2][2])
&& !field[0][0].equals("")) {
return true;
}
return field[0][2].equals(field[1][1])
&& field[0][2].equals(field[2][0])
&& !field[0][2].equals("");
}
private void player1Wins() {
player1Points++;
Toast.makeText(this, "Player 1 wins!", Toast.LENGTH_SHORT).show();
updatePointsText();
resetBoard();
}
private void player2Wins() {
player2Points++;
Toast.makeText(this, "Player 2 wins!", Toast.LENGTH_SHORT).show();
updatePointsText();
resetBoard();
}
private void draw() {
Toast.makeText(this, "Draw!", Toast.LENGTH_SHORT).show();
resetBoard();
}
private void updatePointsText() {
player1.setText(getString(R.string.player_1_0, player1Points));
player2.setText(getString(R.string.player_2_0, player2Points));
}
private void resetBoard() {
for (int x = 0; x < 3; x++) {
for (int y = 0; y < 3; y++) {
buttons[x][y].setText("");
}
}
roundCount = 0;
player1Turn = true;
}
private void resetGame() {
player1Points = 0;
player2Points = 0;
updatePointsText();
resetBoard();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("roundCount", roundCount);
outState.putInt("player1Points", player1Points);
outState.putInt("player2Points", player2Points);
outState.putBoolean("player1Turn", player1Turn);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
roundCount = savedInstanceState.getInt("roundCount");
player1Points = savedInstanceState.getInt("player1Points");
player2Points = savedInstanceState.getInt("player2Points");
player1Turn = savedInstanceState.getBoolean("player1Turn");
}
}
代码在这里...
我创建了一个简单的井字游戏。 gradle
构建没有错误,并且生成了 apk
。
但是在我的 phone 中安装后它显示如下...
java.lang.RuntimeException:
无法启动activity
ComponentInfo{com.codec.dnv.tictactoe/com.codec.dnv.tictactoe.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2814) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892) at android.app.ActivityThread.-wrap11(Unknown Source:0) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1613) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:173) at android.app.ActivityThread.main(ActivityThread.java:6634) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:822) Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference at com.codec.dnv.tictactoe.MainActivity.onCreate(MainActivity.java:42) at android.app.Activity.performCreate(Activity.java:7074) at android.app.Activity.performCreate(Activity.java:7065) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1215) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2767)>
如何克服这个问题?
您在此处为您的 OnClickListener 设置了空值
android.widget.Button.setOnClickListener(android.view.View$OnClickListener)
我会尝试确定它为什么为空,也许它从未被初始化。我们需要查看完整的代码块才能进一步帮助您。
public class MainActivity 扩展 AppCompatActivity 实现 View.OnClickListener {
private Button[][] buttons = new Button[3][3];
private boolean player1Turn = true;
private int roundCount;
private int player1Points;
private int player2Points;
private TextView player1;
private TextView player2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
player1 = findViewById(R.id.player1);
player2 = findViewById(R.id.player2);
for (int x = 0; x < 3; x++) {
for (int y = 0; y < 3; y++) {
String buttonID = "button_" + x + y;
int resID = getResources().getIdentifier(buttonID, "id", getPackageName());
buttons[x][y] = findViewById(resID);
buttons[x][y].setOnClickListener(this);
}
}
Button buttonReset = findViewById(R.id.button_reset);
buttonReset.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
resetGame();
}
});
}
@Override
public void onClick(View v) {
if (!((Button) v).getText().toString().equals("")) {
return;
}
if (player1Turn) {
((Button) v).setText("X");
} else {
((Button) v).setText("Y");
}
roundCount++;
if (checkWin()) {
if (player1Turn) {
player1Wins();
} else {
player2Wins();
}
} else if (roundCount == 9) {
draw();
} else {
player1Turn = !player1Turn;
}
}
private boolean checkWin() {
String[][] field = new String[3][3];
for (int x = 0; x < 3; x++) {
for (int y = 0; y < 3; y++) {
field[x][y] = buttons[x][y].getText().toString();
}
}
for (int x = 0; x < 3; x++) {
if (field[x][0].equals(field[x][1])
&& field[x][0].equals(field[x][2])
&& !field[x][0].equals("")) {
return true;
}
}
for (int x = 0; x < 3; x++) {
if (field[0][x].equals(field[1][x])
&& field[0][x].equals(field[2][x])
&& !field[0][x].equals("")) {
return true;
}
}
if (field[0][0].equals(field[1][1])
&& field[0][0].equals(field[2][2])
&& !field[0][0].equals("")) {
return true;
}
return field[0][2].equals(field[1][1])
&& field[0][2].equals(field[2][0])
&& !field[0][2].equals("");
}
private void player1Wins() {
player1Points++;
Toast.makeText(this, "Player 1 wins!", Toast.LENGTH_SHORT).show();
updatePointsText();
resetBoard();
}
private void player2Wins() {
player2Points++;
Toast.makeText(this, "Player 2 wins!", Toast.LENGTH_SHORT).show();
updatePointsText();
resetBoard();
}
private void draw() {
Toast.makeText(this, "Draw!", Toast.LENGTH_SHORT).show();
resetBoard();
}
private void updatePointsText() {
player1.setText(getString(R.string.player_1_0, player1Points));
player2.setText(getString(R.string.player_2_0, player2Points));
}
private void resetBoard() {
for (int x = 0; x < 3; x++) {
for (int y = 0; y < 3; y++) {
buttons[x][y].setText("");
}
}
roundCount = 0;
player1Turn = true;
}
private void resetGame() {
player1Points = 0;
player2Points = 0;
updatePointsText();
resetBoard();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("roundCount", roundCount);
outState.putInt("player1Points", player1Points);
outState.putInt("player2Points", player2Points);
outState.putBoolean("player1Turn", player1Turn);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
roundCount = savedInstanceState.getInt("roundCount");
player1Points = savedInstanceState.getInt("player1Points");
player2Points = savedInstanceState.getInt("player2Points");
player1Turn = savedInstanceState.getBoolean("player1Turn");
}
}
代码在这里...