Tic Tac Toe按钮按下创建ANR keyDispatchedTimedOut

时间:2013-06-28 16:38:17

标签: java android button onclick

我最近做了一个玩家tic tac toe游戏,我正在使用随机放置Os的简易AI。当我按下的最后一个按钮应该让游戏成为平局时我得到一个ANR,但游戏冻结并停止响应。

这些是我的ANR错误:

06-28 16:01:25.894: E/ActivityManager(63): ANR in g.icstictactoe (g.icstictactoe/.OnePlayer)
06-28 16:01:25.894: E/ActivityManager(63): Reason: keyDispatchingTimedOut
06-28 16:01:25.894: E/ActivityManager(63): Load: 0.81 / 0.33 / 0.25
06-28 16:01:25.894: E/ActivityManager(63): CPU usage from 19103ms to 0ms ago:
06-28 16:01:25.894: E/ActivityManager(63):   98% 677/g.icstictactoe: 98% user + 0% kernel
06-28 16:01:25.894: E/ActivityManager(63):   0.1% 63/system_server: 0% user + 0.1% kernel / faults: 5 minor
06-28 16:01:25.894: E/ActivityManager(63):   0% 41/adbd: 0% user + 0% kernel
06-28 16:01:25.894: E/ActivityManager(63): 100% TOTAL: 99% user + 0.1% kernel
06-28 16:01:25.894: E/ActivityManager(63): CPU usage from 1156ms to 1716ms later:
06-28 16:01:25.894: E/ActivityManager(63):   91% 677/g.icstictactoe: 91% user + 0% kernel
06-28 16:01:25.894: E/ActivityManager(63):     89% 677/g.icstictactoe: 89% user + 0% kernel
06-28 16:01:25.894: E/ActivityManager(63):   8.9% 63/system_server: 7.1% user + 1.7% kernel
06-28 16:01:25.894: E/ActivityManager(63):     7.1% 93/InputDispatcher: 5.3% user + 1.7% kernel
06-28 16:01:25.894: E/ActivityManager(63): 100% TOTAL: 98% user + 1.7% kernel
06-28 16:01:25.914: I/InputDispatcher(63): Dropping event because the pointer is not down.
06-28 16:01:48.365: W/ActivityManager(63):   Force finishing activity g.icstictactoe/.OnePlayer
06-28 16:01:48.395: I/ActivityManager(63): Killing g.icstictactoe (pid=677): user's request
06-28 16:01:48.395: I/Process(63): Sending signal. PID: 677 SIG: 9
06-28 16:01:48.465: I/ActivityManager(63): Process g.icstictactoe (pid 677) has died.

这是我的代码:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.tictactoe);
    count = 0;
    gameOver = false;
    ticTacToe = new Button[3][3];
    ticTacToe[0][0] = (Button) findViewById(R.id.top_left);
    ticTacToe[0][1] = (Button) findViewById(R.id.top);
    ticTacToe[0][2] = (Button) findViewById(R.id.top_right);
    ticTacToe[1][0] = (Button) findViewById(R.id.left);
    ticTacToe[1][1] = (Button) findViewById(R.id.center);
    ticTacToe[1][2] = (Button) findViewById(R.id.right);
    ticTacToe[2][0] = (Button) findViewById(R.id.bottom_left);
    ticTacToe[2][1] = (Button) findViewById(R.id.bottom);
    ticTacToe[2][2] = (Button) findViewById(R.id.bottom_right);
    result = (TextView) findViewById(R.id.result);
    playagain = (Button) findViewById(R.id.playagain);
    for (int i = 0; i < ticTacToe.length; i++)
        for (int j = 0; j < ticTacToe[0].length; j++)
            ticTacToe[i][j].setOnClickListener(this);
    playagain.setOnClickListener(this);
    result.setOnClickListener(this);

}

@Override
public void onClick(View v) {
    switch (v.getId()) {
    case R.id.top_left: findAnswer(0, 0);
        break;
    case R.id.top: findAnswer(0, 1);
        break;
    case R.id.top_right: findAnswer(0, 2);
        break;
    case R.id.left: findAnswer(1, 0);
        break;
    case R.id.center: findAnswer(1, 1);
        break;
    case R.id.right: findAnswer(1, 2);
        break;
    case R.id.bottom_left: findAnswer(2, 0);
        break;
    case R.id.bottom: findAnswer(2, 1);
        break;
    case R.id.bottom_right: findAnswer(2, 2);
        break;
    case R.id.playagain: playagain();
        break;
    }
}

public void findAnswer(int row, int col) {
    String level = "EASY";
    if(level.equals(EASY))
        easyAnswer(row, col);
}

public void easyAnswer(int row, int col)
{
    ticTacToe[row][col].setText("X");
    ticTacToe[row][col].setClickable(false);
    if (!winOrDraw()) { // If X did not win
        int rowO = (int) (Math.random() * 3);
        int colO = (int) (Math.random() * 3);
        while (!ticTacToe[rowO][colO].isClickable()) 
        {
            rowO = (int) (Math.random() * 3);
            colO = (int) (Math.random() * 3);
        }
        ticTacToe[rowO][colO].setText("O");
        ticTacToe[rowO][colO].setClickable(false);
    }
    if(!gameOver)
        winOrDraw();
}

public boolean winOrDraw()
{
    if (checkGame("X")) {
        gameOver = true;
        result.setText("Game Over! X Wins!");
        disableGame();
    } else {
        if (checkGame("O")) {
            gameOver = true;
            result.setText("Game Over! O Wins!");
            disableGame();
        }
    }
    count++;
    if (count == 10 && !gameOver)
    {
        result.setText("This game is a draw!");
        gameOver = true;
    }
    return gameOver;
}

public boolean checkGame(String player) {
    // Horizontal
    if (ticTacToe[0][0].getText().equals(ticTacToe[0][1].getText())
            && ticTacToe[0][0].getText().equals(ticTacToe[0][2].getText())
            && ticTacToe[0][0].getText().equals(player))
        return true;
    else if (ticTacToe[1][0].getText().equals(ticTacToe[1][1].getText())
            && ticTacToe[1][0].getText().equals(ticTacToe[1][2].getText())
            && ticTacToe[1][0].getText().equals(player))
        return true;
    else if (ticTacToe[2][0].getText().equals(ticTacToe[2][1].getText())
            && ticTacToe[2][0].getText().equals(ticTacToe[2][2].getText())
            && ticTacToe[2][0].getText().equals(player))
        return true;
    // Vertical
    else if (ticTacToe[0][0].getText().equals(ticTacToe[1][0].getText())
            && ticTacToe[0][0].getText().equals(ticTacToe[2][0].getText())
            && ticTacToe[0][0].getText().equals(player))
        return true;
    else if (ticTacToe[0][1].getText().equals(ticTacToe[1][1].getText())
            && ticTacToe[0][1].getText().equals(ticTacToe[2][1].getText())
            && ticTacToe[0][1].getText().equals(player))
        return true;
    else if (ticTacToe[0][2].getText().equals(ticTacToe[1][2].getText())
            && ticTacToe[0][2].getText().equals(ticTacToe[2][2].getText())
            && ticTacToe[0][2].getText().equals(player))
        return true;
    // Diagonal
    else if (ticTacToe[0][0].getText().equals(ticTacToe[1][1].getText())
            && ticTacToe[0][0].getText().equals(ticTacToe[2][2].getText())
            && ticTacToe[0][0].getText().equals(player))
        return true;
    else if (ticTacToe[0][2].getText().equals(ticTacToe[1][1].getText())
            && ticTacToe[0][2].getText().equals(ticTacToe[2][0].getText())
            && ticTacToe[0][2].getText().equals(player))
        return true;
    else {
        result.setText("The game continues...");
        return false;
    }
}
public void playagain() {
    for (int i = 0; i < ticTacToe.length; i++)
        for (int j = 0; j < ticTacToe[0].length; j++) {
            ticTacToe[i][j].setClickable(true);
            ticTacToe[i][j].setText("");
        }
    result.setText("Click a button to start game");
    count = 0;
    gameOver = false;
}
public void disableGame() {
    for (int i = 0; i < ticTacToe.length; i++)
        for (int j = 0; j < ticTacToe[0].length; j++)
            ticTacToe[i][j].setClickable(false);
}
}

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:2)

看起来你的winOrDraw检查没有按预期工作,它不会检测到绘制条件,你的应用程序卡在while循环中,随机选择一个空格并检查它是否为空。当游戏以绘制结束时,没有空(可点击)空格,因此while循环是一个无限循环并阻塞主线程,因此ANR。

我敢打赌你的错误是在没有获胜者的情况下检查是否计数== 10来宣布平局,应该是9,不应该是?